在Fortran中一次读取许多文件

时间:2013-12-03 17:23:19

标签: file-io fortran

我有需要在Fortran中读取的500,000个文件,每个文件中有大约14,000个条目(每个条目只有大约100个字符长)。我需要一次处理每个文件的每一行。例如,我需要为所有500,000个文件处理第1行,然后再从文件转到第2行,等等。

我无法一次打开它们(我尝试制作一个文件指针数组并打开它们),因为一次打开的文件太多了。相反,我想做一些如下事情:

 do iline = 1,Nlines
   do ifile = 1,Nfiles
     ! open the file
     ! read a line
     ! close the file
   enddo
 end

希望这允许我一次读取一行(从每个文件),然后转到下一行(在每个文件中)。不幸的是,每次打开文件时,它都会再次从第1行开始。有没有办法打开/关闭文件,然后再从上次停止的地方再次打开文件?

由于

4 个答案:

答案 0 :(得分:3)

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

position="ASIS"

对于尚未连接的单元,未指定实际位置,实际上该位置实际上是大多数系统上文件的开头。

这意味着您必须使用

  read(*,*)

足够的时间来到文件中的正确位置。

您还可以使用stream访问权限。该文件将在开头再次打开,但您可以使用

  read(u,*,pos=n) number

其中n是从先前打开保存的位置。你可以从

获得职位
inquire(unit=u, pos=n)
n = n

您可以使用acess="STREAM"打开文件。

另外500000个打开的文件确实太多了。有多种方法可以查询系统限制以及如何控制它们,但是编译器可能还有一些限制http://www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files/

其他解决方案:您无法将文件内容存储在内存中吗?今天几千兆字节还可以,但对你来说可能还不够。

答案 1 :(得分:0)

您可以尝试使用fseekftell之类的内容。

! 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将检索当前位置,该位置将保存到下一轮的内存中。如果所有条目具有相同的长度,则可以节省数组并只存储一个值。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

所有文件打开/关闭的开销将是一个很大的性能瓶颈。 考虑到你的记忆,你应该尽可能多地阅读每次开放操作:

伪代码:

          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