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. Я бы порекомендовал найти другой подход к проблеме, который не требовал оставлять открытыми тысячи файлов.

Другие вопросы по тегам