Fortran Coder

查看: 6186|回复: 7
打印 上一主题 下一主题

[文件读写] 二进制文件读取

[复制链接]

35

帖子

11

主题

0

精华

熟手

F 币
241 元
贡献
140 点
跳转到指定楼层
楼主
发表于 2021-11-17 10:35:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
大家好,我正在写一个读取二进制文件的程序(也十分感谢论坛对二进制文件的科普文章),在读取过程中,对文件某一段试了两种方法进行读取,发现方法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 )

或者,对于这样的二进制文件读取,有更快的方式吗?
感谢讨论与指正!
分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

213

帖子

2

主题

0

精华

宗师

F 币
2142 元
贡献
875 点

规矩勋章

沙发
发表于 2021-11-17 21:01:34 | 只看该作者
方法B没有提供rec=选项,则作为顺序文件读取。

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

板凳
发表于 2021-11-17 21:49:18 | 只看该作者
http://binary.w.fcode.cn/
此处了解 Fortran 经典的二进制文件读写方法。

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

35

帖子

11

主题

0

精华

熟手

F 币
241 元
贡献
140 点
地板
 楼主| 发表于 2021-11-18 18:15:09 | 只看该作者
fcode 发表于 2021-11-17 21:49
http://binary.w.fcode.cn/
此处了解 Fortran 经典的二进制文件读写方法。

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

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

5#
发表于 2021-11-19 10:16:15 | 只看该作者
stream方式读取效率没有其他两种方式高,但是差别并不大。
相比于 stream 方式操作上的灵活优势,我觉得是完全值得的。

13

帖子

4

主题

0

精华

入门

F 币
88 元
贡献
52 点
6#
发表于 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个字符的长度。是哪里出问题了呢?
[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'的操作问题出在哪。

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

7#
发表于 2022-1-13 20:34:08 | 只看该作者
如果你学会了 stream,那你在新写代码中,完全不必去学 direct 了。真的
stream是完全可替代direct的,并且更灵活易读。就好像,都有手机了,何必去学如何使用BB机呢?
唯一有学习必要的场景,是你需要读一些使用了direct方式的老代码。

101

帖子

0

主题

0

精华

大师

F 币
670 元
贡献
299 点

规矩勋章元老勋章新人勋章

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

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

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

评分

参与人数 1F 币 +3 收起 理由
fcode + 3

查看全部评分

天之道,损有余而补不足
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-12-25 00:51

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表