forrtl: 严重 (104): 不正确的 STATUS= 连接文件的说明符值,单元 -1,文件 CONOUT$
forrtl: severe (104): incorrect STATUS= specifier value for connected file, unit -1, file CONOUT$
我有一个 Fortran 例程,它打开大量文本文件从时间循环写入数据。这个例程使用open
和newunit
选项,这个单元存储在一个对象中,以便以后在文件中写入东西。这在大多数情况下都可以正常工作,但是当程序需要同时打开大量 N 个文件时,我会收到以下错误:
**forrtl: severe (104): incorrect STATUS= specifier value for connected file, unit -1, file CONOUT$**
引用 createFiles
子程序中的第一个 open
函数。无论文件是否已经存在,都会发生此错误。我不知道这是否有帮助,但在这个阶段应该生成的新单位是 -32768
.
我包含了一个最小的代码示例 "timeSeries" class 包括一个创建两个文件的例程:
- 第一个文件
fileName1
在里面写东西后直接打开和关闭
- 第二个文件
fileName2
保持打开状态,以便稍后写入在时间循环中计算的内容,并在时间循环结束时关闭
示例由以下两个文件组成。它打破了 i=32639.
main.f90 :
program writeFiles
use TS
logical :: stat
integer :: i, istep, N, NtimeSteps
character(len=16) :: fileName1, fileName2
character(len=300) :: path
type(timeSeries), dimension(:), allocatable :: myTS
call getcwd( path )
path = trim(path) // '\Output_files'
inquire(directory = trim(path), exist = stat )
if (.not. stat) call system("mkdir " // '"' // trim(path) // '"' )
N = 50000
NtimeSteps = 100
allocate(myTS(N))
do i = 1, N
write(fileName1,'(a6,i6.6,a4)') 'file1_', i, '.txt'
write(fileName2,'(a6,i6.6,a4)') 'file2_', i, '.txt'
call myTS(i)%createFiles(trim(path),fileName1,fileName2)
end do
do istep = 1, NtimeSteps
#
#compute stuff
#
do i = 1, N
write(myTS(i)%fileUnit,*) 'stuff'
end do
end do
do i = 1, N
close(myTS(i)%fileUnit)
end do
end program writeFiles
模块.f90 :
module TS
type timeSeries
integer :: fileUnit
contains
procedure :: createFiles => timeSeries_createFiles
end type timeSeries
contains
subroutine timeSeries_createFiles(this,dir,fileName1,fileName2)
class(timeSeries) :: this
character(*) :: dir, fileName1, fileName2
open(newunit = this%fileUnit , file = dir // '\' // fileName1, status = 'replace') !error occurs here after multiple function calls
write(this%fileUnit,*) 'Write stuff'
close(this%fileUnit)
open(newunit = this%fileUnit , file = dir // '\' // fileName2, status = 'replace')
end subroutine timeSeries_createFiles
end module
知道这个错误的原因吗?同时打开的文件数量有限制吗?会不会是内存问题?
我正在使用 Intel(R) Visual Fortran 编译器 17.0.4.210
Windows 有一个有趣的习惯,即在关闭后的短时间内不会释放已关闭文件的所有资源。几十年来,我断断续续地看到过这种问题。我通常的建议是,当您打算在同一文件后立即执行另一个 OPEN 时,在 CLOSE 后持续半秒调用 SLEEPQQ。但你不会在这里这样做。
这里还有更多令人费解的地方。当打开显式文件并使用 NEWUNIT 时,不应出现引用单元 -1 和 CONOUT$ 的错误消息。在 Intel 的实施中,NEWUNIT 数字从 -129 开始并从那里变得更负。 Unit -1 用于 PRINT 或 WRITE(*),CONOUT$ 是控制台。 STATUS='REPLACE' 对于连接到控制台的单元无效。 newunit 编号将是 -32768 这说明并暗示了英特尔库中 NEWUNIT 的内部限制。
我自己做了一个测试,发现如果你使用 NEWUNIT 并关闭单元,单元编号会低至 -16384,然后循环回到 -129。如果您确实要关闭单元,那没关系,但您永远不会关闭打开的第二个文件,因此您至少达到了打开的 NEWUNIT 文件的最大数量。我建议找出一种不同的方法来解决不需要打开数千个文件的问题。
我有一个 Fortran 例程,它打开大量文本文件从时间循环写入数据。这个例程使用open
和newunit
选项,这个单元存储在一个对象中,以便以后在文件中写入东西。这在大多数情况下都可以正常工作,但是当程序需要同时打开大量 N 个文件时,我会收到以下错误:
**forrtl: severe (104): incorrect STATUS= specifier value for connected file, unit -1, file CONOUT$**
引用 createFiles
子程序中的第一个 open
函数。无论文件是否已经存在,都会发生此错误。我不知道这是否有帮助,但在这个阶段应该生成的新单位是 -32768
.
我包含了一个最小的代码示例 "timeSeries" class 包括一个创建两个文件的例程:
- 第一个文件
fileName1
在里面写东西后直接打开和关闭 - 第二个文件
fileName2
保持打开状态,以便稍后写入在时间循环中计算的内容,并在时间循环结束时关闭
示例由以下两个文件组成。它打破了 i=32639.
main.f90 :
program writeFiles
use TS
logical :: stat
integer :: i, istep, N, NtimeSteps
character(len=16) :: fileName1, fileName2
character(len=300) :: path
type(timeSeries), dimension(:), allocatable :: myTS
call getcwd( path )
path = trim(path) // '\Output_files'
inquire(directory = trim(path), exist = stat )
if (.not. stat) call system("mkdir " // '"' // trim(path) // '"' )
N = 50000
NtimeSteps = 100
allocate(myTS(N))
do i = 1, N
write(fileName1,'(a6,i6.6,a4)') 'file1_', i, '.txt'
write(fileName2,'(a6,i6.6,a4)') 'file2_', i, '.txt'
call myTS(i)%createFiles(trim(path),fileName1,fileName2)
end do
do istep = 1, NtimeSteps
#
#compute stuff
#
do i = 1, N
write(myTS(i)%fileUnit,*) 'stuff'
end do
end do
do i = 1, N
close(myTS(i)%fileUnit)
end do
end program writeFiles
模块.f90 :
module TS
type timeSeries
integer :: fileUnit
contains
procedure :: createFiles => timeSeries_createFiles
end type timeSeries
contains
subroutine timeSeries_createFiles(this,dir,fileName1,fileName2)
class(timeSeries) :: this
character(*) :: dir, fileName1, fileName2
open(newunit = this%fileUnit , file = dir // '\' // fileName1, status = 'replace') !error occurs here after multiple function calls
write(this%fileUnit,*) 'Write stuff'
close(this%fileUnit)
open(newunit = this%fileUnit , file = dir // '\' // fileName2, status = 'replace')
end subroutine timeSeries_createFiles
end module
知道这个错误的原因吗?同时打开的文件数量有限制吗?会不会是内存问题?
我正在使用 Intel(R) Visual Fortran 编译器 17.0.4.210
Windows 有一个有趣的习惯,即在关闭后的短时间内不会释放已关闭文件的所有资源。几十年来,我断断续续地看到过这种问题。我通常的建议是,当您打算在同一文件后立即执行另一个 OPEN 时,在 CLOSE 后持续半秒调用 SLEEPQQ。但你不会在这里这样做。
这里还有更多令人费解的地方。当打开显式文件并使用 NEWUNIT 时,不应出现引用单元 -1 和 CONOUT$ 的错误消息。在 Intel 的实施中,NEWUNIT 数字从 -129 开始并从那里变得更负。 Unit -1 用于 PRINT 或 WRITE(*),CONOUT$ 是控制台。 STATUS='REPLACE' 对于连接到控制台的单元无效。 newunit 编号将是 -32768 这说明并暗示了英特尔库中 NEWUNIT 的内部限制。
我自己做了一个测试,发现如果你使用 NEWUNIT 并关闭单元,单元编号会低至 -16384,然后循环回到 -129。如果您确实要关闭单元,那没关系,但您永远不会关闭打开的第二个文件,因此您至少达到了打开的 NEWUNIT 文件的最大数量。我建议找出一种不同的方法来解决不需要打开数千个文件的问题。