File io 在Fortran中同时读取多个文件

File io 在Fortran中同时读取多个文件,file-io,fortran,File Io,Fortran,我有500000个文件,我需要用Fortran阅读,每个文件有14000个条目(每个条目只有大约100个字符长)。我需要一次处理每个文件的每一行。例如,我需要处理所有500000个文件的第1行,然后再从文件中转到第2行,以此类推 我不能一次全部打开它们(我尝试创建一个文件指针数组并将它们全部打开),因为一次打开的文件太多了。相反,我想做以下几件事: do iline = 1,Nlines do ifile = 1,Nfiles ! open the file ! re

我有500000个文件,我需要用Fortran阅读,每个文件有14000个条目(每个条目只有大约100个字符长)。我需要一次处理每个文件的每一行。例如,我需要处理所有500000个文件的第1行,然后再从文件中转到第2行,以此类推

我不能一次全部打开它们(我尝试创建一个文件指针数组并将它们全部打开),因为一次打开的文件太多了。相反,我想做以下几件事:

 do iline = 1,Nlines
   do ifile = 1,Nfiles
     ! open the file
     ! read a line
     ! close the file
   enddo
 end
希望这能让我一次读一行(从每个文件中),然后转到下一行(在每个文件中)。不幸的是,每次我打开文件,它都会再次从第1行开始。有没有办法打开/关闭一个文件,然后在之前停止的位置再次打开它


谢谢

不幸的是,在标准Fortran中,以这种方式是不可能的。即使你指定

position="ASIS"
对于尚未连接的单元,实际位置将未指定,并且在大多数系统上实际上是文件的开头

这意味着你必须使用

  read(*,*)
有足够的时间在文件中找到正确的位置

您还可以使用
stream
access。文件将在开始时再次打开,但您可以使用

  read(u,*,pos=n) number
其中
n
是上次打开时保存的位置。你可以从

inquire(unit=u, pos=n)
n = n
您可以使用
acess=“STREAM”
打开文件

另外,打开50万个文件确实太多了。有一些方法可以查询系统限制以及如何控制它们,但是编译器也可能有一些限制

其他解决方案:您不能将文件的内容存储在内存中吗?今天,几GB是可以的,但对您来说可能还不够。

您可以尝试使用和,如下所示

! initialize an array of 0's
do iline = 1,Nlines
   do ifile = 1,Nfiles
     ! open the file
     ! fseek(fd, array(ifile))
     ! read a line
     ! array(ifile)=ftell(fd)
     ! close the file
   enddo
 end

(未测试的)想法是将每个文件的偏移量存储在一个数组中,并在打开文件时将光标定位在该位置。然后,读取一行后,
ftell
检索当前位置,并将其保存到内存中以供下一轮使用。如果所有条目的长度相同,则可以保留数组并只存储一个值。

如果文件具有固定的记录长度,即恒定的记录长度,则可以使用直接访问。然后,您可以“直接”读取特定记录。然而,一个很大的“如果”。

所有文件打开/关闭的开销将是一个很大的性能瓶颈。 在给定内存的情况下,应尽可能多地读取每个打开操作的内容:

伪代码:

          loop until done:
            loop over all files:
                open
                fseek !as in damiens answer
                read N lines into array ! N=100 eg.
                save ftell value for file
                close
            end file loop
            loop over N output files:
                open
                write array data
                close

所有数据的内容都超过130 GB。我无法将其存储到内存中,否则这将是一个简单的修复。我实际上是这样读的,因为所有的数据都在一个文件中,我必须以一种需要4.5年才能完成的方式来读!所以是的,我可以改变算法,目前的版本是目前为止最好的选择!您也可以尝试
访问,但速度可能不会更快。太棒了。在我尝试这个之前,我使用了一个穷人的
FSEEK
,只是用reads搜索指定的行。对10个文件执行此操作需要约8分钟,但现在使用
FSEEK
非标准Fortran将时间缩短到约4秒。我认为此标题有点误导,因为问题不是实际同时打开所有这些文件。对于管理如此大量的文件和数据,这似乎也是一种令人惊讶的非复杂化方法。你考虑过建立一个数据库管理系统吗?