Fortran Coder

查看: 2915|回复: 4
打印 上一主题 下一主题

[文件读写] 将数据写入二进制文件后,怎么正确地读出来?

[复制链接]

80

帖子

26

主题

0

精华

专家

F 币
280 元
贡献
150 点
跳转到指定楼层
楼主
发表于 2022-10-2 12:50:25 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
[Fortran] 纯文本查看 复制代码
Program PointTS

  Implicit none
!  Integer(kind=1)
  Integer(kind=4) i, j, k, m
  Real(kind=8) EETIME

  Real(kind=8) EETIME_1

  Integer(kind=4), Allocatable :: KSZ_Global(:,:), KSZ_Global_1(:,:)

  Allocate(KSZ_Global(2,3))
  Allocate(KSZ_Global_1(2,3))

  EETIME = 1
  k = 0
  Do i = 1, 3
     Do j = 1,2
        KSZ_Global(j,i) = i+j+k
        k = k + 1
     End Do
  End Do

  Open (Unit=32, File="Matrix.bin", Status='Unknown')
  Close(Unit=32, Status='DELETE')
  Open(Unit=32,File="Matrix.bin",Status="new",Access='sequential',FORM='unformatted')
  Do k = 1, 3
     Write(32) EETIME
     Write(32) ((KSZ_Global(i,j),j=1,3), i=1,2)
     EETIME =  EETIME + 1.0     
     KSZ_Global = KSZ_Global + 1
  End Do
  Close(32)


  Open(Unit=32,File="Matrix.bin",Status="old",Access='stream',FORM='unformatted')
  Do k = 1, 3
     Inquire(32, Pos = m)

     Read(32)   EETIME_1
     Inquire(32, Pos = m)
     Write(6,*) EETIME_1

     Read(32)   ((KSZ_Global_1(i,j),j=1,3), i=1,2)
     Inquire(32, Pos = m)     
     Write(6,*) ((KSZ_Global_1(i,j),j=1,3), i=1,2)
  End Do
  Close(32)
End Program
上面的代码是为了验证把双精度EETIME, 数组KSZ_Global, 写进Matrix.bin这个二进制文件后,然后再把它正确地读出来,但不知为何,读出来的第1个 EETIME_1 = 3.9525251667299724E-323,KSZ_Global_1 也与原来的 KSZ_Global  不一样,请教大家,问题出在哪儿?

微信图片_20221002124611.png (7.47 KB, 下载次数: 186)

微信图片_20221002124611.png
分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

168

帖子

2

主题

1

精华

大师

Vim

F 币
1021 元
贡献
486 点

规矩勋章

沙发
发表于 2022-10-3 09:40:08 | 只看该作者
Fortran流文件-读写二进制任意位置

二进制的读写比较推荐流文件的格式,只需要按照顺序读取即可,旧的方式的需要考虑recl,比较麻烦

80

帖子

26

主题

0

精华

专家

F 币
280 元
贡献
150 点
板凳
 楼主| 发表于 2022-10-4 19:16:56 | 只看该作者
本帖最后由 静待花开 于 2022-10-4 19:18 编辑
Transpose 发表于 2022-10-3 09:40
Fortran流文件-读写二进制任意位置

二进制的读写比较推荐流文件的格式,只需要按照顺序读取即可,旧的方式 ...

谢谢回复。
我是在尝试read一个开源程序输出的二进制文件,它write时采用的是binary,sequential,没有用stream。但我自己就是读不出来正确值,就用上面的代码做了试验。所以write文件的方式是按这个开源程序,也是没有办法,可否指教下问题出在哪里。

54

帖子

0

主题

0

精华

实习版主

F 币
653 元
贡献
214 点

元老勋章新人勋章

QQ
地板
发表于 2022-10-7 17:07:03 | 只看该作者
用 sequential 方式写入的数据,前后会多一个 integer 来表示当前记录的长度。
所以用 stream 读取的时候,需要用一个 integer 来占位。(例子中的m)

[Fortran] 纯文本查看 复制代码
Program PointTS
  Implicit none
  Integer(kind=4) :: i, j, k = 0, m
  Real(kind=8)    :: EETIME=1,EETIME_1
  Integer(kind=4), Allocatable,dimension(:,:) :: KSZ_Global, KSZ_Global_1
  Allocate(KSZ_Global(2,3),KSZ_Global_1(2,3))
  Do i = 1, 3
    Do j = 1,2
      KSZ_Global(j,i) = i+j+k
      k = k + 1
    End Do
  End Do
  Open(Unit=32,File="Matrix.bin",Status="replace",Access='sequential',FORM='unformatted')
  Do k = 1, 3
    Write(32) EETIME
    Write(32) KSZ_Global
    EETIME =  EETIME + 1.0
    KSZ_Global = KSZ_Global + 1
  End Do
  Close(32)
  Open(Unit=32,File="Matrix.bin",Status="old",Access='stream')
  Do k = 1, 3
    Read(32)   m,EETIME_1,m
    Read(32)   m,KSZ_Global_1,m
    Write(*,*) EETIME_1
    Write(*,*) KSZ_Global_1
  End Do
  Close(32)
End Program PointTS

评分

参与人数 1F 币 +3 收起 理由
fcode + 3 教科书级别~

查看全部评分

80

帖子

26

主题

0

精华

专家

F 币
280 元
贡献
150 点
5#
 楼主| 发表于 2022-10-20 20:08:48 | 只看该作者
佩服,佩服,高手!非常感谢
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

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

GMT+8, 2024-12-24 02:53

Powered by Tencent X3.4

© 2013-2024 Tencent

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