I have a Fortran routine that opens a lot of text files write data from a time loop. This routine uses open
with the newunit
option, this unit is stored in an object in order to write things in files later. This works fine most of the time but when the program needs to open a large number N of files at the same time I get the following error:
**forrtl: severe (104): incorrect STATUS= specifier value for connected file, unit -1, file CONOUT$**
reffering to the first open
function in createFiles
subroutine. This error occurs whether the file already exists or not. I don't know if this might help but at this stage the new unit that should be generated would be -32768
.
I include a minimal code sample with a "timeSeries" class including a routine that creates two files:
fileName1
is opened and closed directy after writing stuff insidefileName2
is kept open in order to write things comùputed in a time loop later and closed at the end of the time loopThe example is composed of the two following files. It breaks for 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
module.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
Any idea about the reason for this error? Is there a limitation for the number of files opened at the same time? Could it be related to a memory issue?
I'm using Intel(R) Visual Fortran Compiler 17.0.4.210
Windows has this interesting habit of not releasing all the resources for a closed file for a short time after you do a close. I have seen this sort of problem on and off for decades. My usual recommendation is to put a call to SLEEPQQ with a duration of half a second after a CLOSE when you intend to do another OPEN soon after on the same file. But you're not doing that here.
There's more here that is puzzling. The error message referring to unit -1 and CONOUT$ should not occur when opening an explicit file and using NEWUNIT. In Intel's implementation, NEWUNIT numbers start at -129 and go more negative from there. Unit -1 is used for PRINT or WRITE(*), and CONOUT$ is the console. STATUS='REPLACE' would not be valid for a unit connected to the console. That the newunit number would be -32768 is telling and suggests an internal limit for NEWUNIT in the Intel libraries.
I did a test of my own and see that if you use NEWUNIT and close the unit, the unit numbers go as low as -16384 before cycling back to -129. That's ok if indeed you're closing the units, but you're never closing the second file you open, so you're at least hitting a maximum number of NEWUNIT files open. I would recommend figuring out a different way of approaching the problem that didn't require leaving thousands of files open.