forrtl: суровый (104): неверный STATUS= значение спецификатора для подключенного файла, единица -1, файл CONOUT$
У меня есть подпрограмма на Фортране, которая открывает множество текстовых файлов для записи данных из временного цикла. Эта рутина использует open
с newunit
Опция, этот блок хранится в объекте, чтобы записать вещи в файлы позже. Это работает нормально в большинстве случаев, но когда программе нужно открыть большое количество файлов одновременно, я получаю следующую ошибку:
**forrtl: severe (104): incorrect STATUS= specifier value for connected file, unit -1, file CONOUT$**
отсылка к первому open
функция в createFiles
подпрограмма. Эта ошибка возникает независимо от того, существует файл или нет. Я не знаю, может ли это помочь, но на этом этапе новый генерируемый модуль будет -32768
,
Я включил минимальный пример кода с классом "timeSeries", включая подпрограмму, которая создает два файла:
- первый файл
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
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
Есть идеи о причине этой ошибки? Есть ли ограничение на количество одновременно открытых файлов? Может ли это быть связано с проблемой памяти?
Я использую Intel(R) Visual Fortran Compiler 17.0.4.210
1 ответ
У Windows есть интересная привычка не выпускать все ресурсы для закрытого файла в течение короткого времени после того, как вы сделаете закрытие. Я видел такую проблему время от времени. Моя обычная рекомендация - сделать вызов SLEEPQQ продолжительностью полсекунды после ЗАКРЫТИЯ, если вы вскоре после этого собираетесь сделать еще одно ОТКРЫТОЕ для того же файла. Но вы не делаете это здесь.
Здесь есть еще кое-что, что вызывает недоумение. Сообщение об ошибке, относящееся к единице -1 и CONOUT$, не должно появляться при открытии явного файла и использовании NEWUNIT. В реализации Intel числа NEWUNIT начинаются с -129 и оттуда идут более отрицательно. Модуль -1 используется для PRINT или WRITE(*), а CONOUT$ - консоль. STATUS='REPLACE' не будет действительным для устройства, подключенного к консоли. То, что номер нового блока будет -32768, говорит о внутреннем ограничении NEWUNIT в библиотеках Intel.
Я провел свой собственный тест и увидел, что если вы используете NEWUNIT и закроете устройство, номера устройств снизятся до -16384, прежде чем вернуться к -129. Это нормально, если вы действительно закрываете блоки, но никогда не закрываете второй открытый файл, так что вы, по крайней мере, нажимаете на максимальное количество открытых файлов NEWUNIT. Я бы порекомендовал найти другой подход к проблеме, который не требовал оставлять открытыми тысячи файлов.