jojo9 发表于 2021-11-17 10:35:46

二进制文件读取

大家好,我正在写一个读取二进制文件的程序(也十分感谢论坛对二进制文件的科普文章),在读取过程中,对文件某一段试了两种方法进行读取,发现方法A可行,而方法B运行报错。想请教一下各位大佬问题出在哪。

方法A:
do j=1, n
    irec=irec+1
    read(13, rec=irec) array(j)   
enddo

方法B:
read(13) ( array(j), j=1, n )

13 是文件的unit,方法B运行报的错是: forrtl: severe (259): sequential-access I/O to unit open for direct access, unit 13, file D:......
在文件的开头,是这样打开的文件: open( 13, file='...', access='Direct', form='Unformatted', recl=1 )

或者,对于这样的二进制文件读取,有更快的方式吗?
感谢讨论与指正!

风平老涡 发表于 2021-11-17 21:01:34

方法B没有提供rec=选项,则作为顺序文件读取。

fcode 发表于 2021-11-17 21:49:18

http://binary.w.fcode.cn/
此处了解 Fortran 经典的二进制文件读写方法。

http://stream.w.fcode.cn/
现代Fortran 建议用上面的 stream 方法。

jojo9 发表于 2021-11-18 18:15:09

fcode 发表于 2021-11-17 21:49
http://binary.w.fcode.cn/
此处了解 Fortran 经典的二进制文件读写方法。



感谢感谢,就是看的第一个链接的文章才写出程序的。刚看了第二个链接想请教一下您,用‘流文件’的方式读取文件在速度上,(比如,同样将文件中的一段读入到一个数组),是否比‘直接读取‘的方式要快呢?我看描述里有“它并不把二进制文件视为一个一个的“记录”,而是视为一个整体”。

fcode 发表于 2021-11-19 10:16:15

stream方式读取效率没有其他两种方式高,但是差别并不大。
相比于 stream 方式操作上的灵活优势,我觉得是完全值得的。

navoski 发表于 2022-1-13 17:23:07

本帖最后由 navoski 于 2022-1-13 18:05 编辑

fcode 发表于 2021-11-17 21:49
http://binary.w.fcode.cn/
此处了解 Fortran 经典的二进制文件读写方法。


想请教一下。
如果我要写一个二进制文件,但是每条rec的长度recl不一样。
我需要打开文件设置一个recl,写入数据,然后关闭;在打开文件设置一个recl,写入数据,然后关闭;这样操作是否正确?如果操作是正确的,我用下面的代码生成文件,打开后,第一个rec,也变为了57个字符的长度。是哪里出问题了呢?
    open(unit=10, file='powerdensity.bin', access='direct', &
            action='write', form='unformatted', recl=26, status='replace')
    write(10,rec=1) 'CCCCCCCCCCCCCCCCCCCCCCCCCC'
    close(unit=10)
   
    open(unit=10, file='powerdensity.bin', access='direct', &
            action='write', form='unformatted', recl=57, status='old')
    write(10,rec=2) 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
    close(unit=10)

我用access=‘stream’,可以解决这个问题。但是还是想弄清楚access='direct'的操作问题出在哪。

fcode 发表于 2022-1-13 20:34:08

如果你学会了 stream,那你在新写代码中,完全不必去学 direct 了。真的
stream是完全可替代direct的,并且更灵活易读。就好像,都有手机了,何必去学如何使用BB机呢?
唯一有学习必要的场景,是你需要读一些使用了direct方式的老代码。

胡文刚 发表于 2022-1-14 17:40:36

navoski 发表于 2022-1-13 17:23
想请教一下。
如果我要写一个二进制文件,但是每条rec的长度recl不一样。
我需要打开文件设置一个recl,写 ...

recl是打开文件时,读取程序设置的长度。他和文件本身的内容没有关系。
一个长度为N的文件。你可以用任何recl长度打开,去读写。
如果你用 recl = 26 打开,每次就能读写26个长度为一个单位。
如果你用 recl = 57 打开,每次就能读写57个长度为一个单位。

就好像一条公路,它的长度是固定的。不管你的汽车是用公里计算,还是英里计算。
或者你第一次跑这条路用公里计算,第二次用英里计算。都不影响这条路的实质。
页: [1]
查看完整版本: 二进制文件读取