Fortran Coder

标题: 二进制文件读取 [打印本页]

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

方法A:
[Fortran] 纯文本查看 复制代码
do j=1, n
    irec=irec+1
    read(13, rec=irec) array(j)     
enddo


方法B:
[Fortran] 纯文本查看 复制代码
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
方法B没有提供rec=选项,则作为顺序文件读取。
作者: fcode    时间: 2021-11-17 21:49
http://binary.w.fcode.cn/
此处了解 Fortran 经典的二进制文件读写方法。

http://stream.w.fcode.cn/
现代  Fortran 建议用上面的 stream 方法。
作者: jojo9    时间: 2021-11-18 18:15
fcode 发表于 2021-11-17 21:49
http://binary.w.fcode.cn/
此处了解 Fortran 经典的二进制文件读写方法。

感谢感谢,就是看的第一个链接的文章才写出程序的。刚看了第二个链接想请教一下您,用‘流文件’的方式读取文件在速度上,(比如,同样将文件中的一段读入到一个数组),是否比‘直接读取‘的方式要快呢?我看描述里有“它并不把二进制文件视为一个一个的“记录”,而是视为一个整体”。
作者: fcode    时间: 2021-11-19 10:16
stream方式读取效率没有其他两种方式高,但是差别并不大。
相比于 stream 方式操作上的灵活优势,我觉得是完全值得的。
作者: navoski    时间: 2022-1-13 17:23
本帖最后由 navoski 于 2022-1-13 18:05 编辑
fcode 发表于 2021-11-17 21:49
http://binary.w.fcode.cn/
此处了解 Fortran 经典的二进制文件读写方法。

想请教一下。
如果我要写一个二进制文件,但是每条rec的长度recl不一样。
我需要打开文件设置一个recl,写入数据,然后关闭;在打开文件设置一个recl,写入数据,然后关闭;这样操作是否正确?如果操作是正确的,我用下面的代码生成文件,打开后,第一个rec,也变为了57个字符的长度。是哪里出问题了呢?
[Fortran] 纯文本查看 复制代码
    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
如果你学会了 stream,那你在新写代码中,完全不必去学 direct 了。真的
stream是完全可替代direct的,并且更灵活易读。就好像,都有手机了,何必去学如何使用BB机呢?
唯一有学习必要的场景,是你需要读一些使用了direct方式的老代码。


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

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

就好像一条公路,它的长度是固定的。不管你的汽车是用公里计算,还是英里计算。
或者你第一次跑这条路用公里计算,第二次用英里计算。都不影响这条路的实质。





欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2