【问题标题】:Reading MANY files at once in Fortran在 Fortran 中一次读取多个文件
【发布时间】:2013-12-03 17:23:19
【问题描述】:

我有 500,000 个文件需要在 Fortran 中读取,每个文件中有大约 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 行开始。有什么方法可以打开/关闭文件,然后在您之前离开的地方再次打开它?

谢谢

【问题讨论】:

  • 我认为标题有点误导,因为问题不在于实际同时打开所有这些文件。管理如此大量的文件和数据似乎也是一种令人惊讶的简单方法。您是否考虑过建立数据库管理系统?

标签: file-io fortran


【解决方案1】:

不幸的是,在标准 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/

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

【讨论】:

  • 所有数据的内容超过 130 GB。我无法将其存储到内存中,否则这将是一个简单的修复。我实际上是这样阅读它的,因为所有数据都在一个文件中,而我必须以一种大约需要 4.5 年才能完成的方式来阅读它!所以是的,我可以改变算法,目前的构建是迄今为止最好的选择!
  • 您也可以尝试stream 访问,但可能不会更快。
【解决方案2】:

您可以尝试在以下内容中使用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 就会检索当前位置,并将其保存到内存中以供下一轮使用。如果所有条目的长度相同,则可以省略数组并只存储一个值。

【讨论】:

  • 太棒了。在我尝试这个之前,我通过一个穷人的FSEEK 去寻找带有读取的指定行。处理 10 个文件需要大约 8 分钟,但现在使用 FSEEK 时间已降至大约 4 秒
  • 不是标准的 Fortran。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    所有文件打开/关闭的开销将是一个很大的性能瓶颈。 考虑到您拥有的任何内存,您应该尽可能多地阅读每个打开的操作:

    伪代码:

              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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-10
      • 2011-11-26
      • 2020-03-13
      • 1970-01-01
      • 1970-01-01
      • 2021-11-19
      相关资源
      最近更新 更多