Fortran Coder

查看: 24302|回复: 11
打印 上一主题 下一主题

[文件读写] 将文本文件转化为二进制文件,然后再转出来

[复制链接]

712

帖子

4

主题

0

精华

大师

农村外出务工人员

F 币
607 元
贡献
311 点

新人勋章爱心勋章水王勋章元老勋章热心勋章

楼主
发表于 2017-10-30 12:46:27 | 显示全部楼层
本帖最后由 楚香饭 于 2017-10-30 12:53 编辑

你这种问题不太容易用二进制存储,因为每个 block 的文本头部都不一样长。
后面用二进制读取的时候,不知道读多少文本头部。

如果你非要转二进制,看下面代码的修改

[Fortran] 纯文本查看 复制代码
program jack01
  implicit none
  character(len = 66) buffer
  integer :: num = 0
  real(kind = 4) :: a, b
  integer :: status = 0
  integer i
  integer, parameter :: lines = 18 !//文本只算18行
  logical alive

  inquire(file = 'new.txt',exist = alive)
  if(.not.alive) then
    write(*,*) "new.txt does not exist"
    stop
  end if
  !打开输入输出文件
  open(unit = 14, file = 'new.txt')
  open(unit = 15, file = 't.bin', access = 'stream')!//stream是一个很霸道的二进制读写方式
CY: Do  !//命名循环
    !转存前面19行的内容
    do  i = 1, lines
      read(14, fmt = "(A66)",iostat = status) buffer
      if(status /= 0) exit CY
      write(15) trim(buffer) !//trim一下以便减小尺寸
    end do
    read(14,*,iostat=status) num !//获得行数
    if(status /= 0) exit CY
    !转存实数部分的内容
    do  i = 1, num
      read(14, *, iostat = status) a, b
      if(status /= 0) exit CY
      write(15) a, b
    end do
  End Do CY
  close(12)
  close(13)  
end program jack01

712

帖子

4

主题

0

精华

大师

农村外出务工人员

F 币
607 元
贡献
311 点

新人勋章爱心勋章水王勋章元老勋章热心勋章

沙发
发表于 2017-10-31 08:36:50 | 显示全部楼层
本帖最后由 楚香饭 于 2017-10-31 08:42 编辑

可以把文本的大小也写在二进制文件里。

以下代码在windows上运行。如果要在其他操作系统上运行,建议修改 crlf 的定义。

[Fortran] 纯文本查看 复制代码
program jack02
  implicit none
  integer :: status , n , i
  Real :: a , b
  character(len=1) , allocatable :: text(:)
  open(unit = 15, file = 't.bin', access = 'stream')!//stream是一个很霸道的二进制读写方式
  open(unit = 14, file = 'newback.txt')
  Do 
    Read(15,iostat=status) n !//得到文本大小
    if(status/= 0) exit
    if(n==0) exit
    Allocate(text(n))
    Read(15) text
    Write(14,'(a,\)') text
    Deallocate(text)
    Read(15,iostat=status) n !//得到二进制大小
    if(status/= 0) exit
    write(14,*) n
    Do i = 1 , n
      Read(15) a , b 
      Write(14,*) a , b
    End Do
  End Do
End Program jack02


[Fortran] 纯文本查看 复制代码
program jack01
  implicit none
  character(len = 66) buffer
  integer :: num = 0
  real(kind = 4) :: a, b
  integer :: status = 0
  integer i , locBegin , locEnd
  integer, parameter :: lines = 18 !//文本只算18行
  character(len=*) , parameter :: crlf = char(z'd') // char(z'a')!//换行符,不同操作系统不一样
  logical alive

  inquire(file = 'new.txt',exist = alive)
  if(.not.alive) then
    write(*,*) "new.txt does not exist"
    stop
  end if
  !打开输入输出文件
  open(unit = 14, file = 'new.txt')
  open(unit = 15, file = 't.bin', access = 'stream')!//stream是一个很霸道的二进制读写方式
CY: Do  !//命名循环
    !转存前面18行的内容
    write(15) 0 !//先输出一个0,表示大小
    Inquire( 15 , pos = locBegin ) !//查询块开始位置
    do  i = 1, lines
      read(14, fmt = "(A66)",iostat = status) buffer
      if(status /= 0) exit CY
      write(15) trim(buffer) , crlf !//trim一下以便减小尺寸,每行输出换行符
    end do
    Inquire( 15 , pos = locEnd ) !//查询块结束位置
    write(15,pos=locBegin-4) locEnd-locBegin !//在开始前4个字节写入大小
    read(14,*,iostat=status) num !//获得行数
    if(status /= 0) exit CY
    write(15,pos=locEnd) num !//回到块结束,写入实数部分的大小
    !转存实数部分的内容
    do  i = 1, num
      read(14, *, iostat = status) a, b
      if(status /= 0) exit CY
      write(15) a, b
    end do
  End Do CY
  close(12)
  close(13)  
end program jack01


712

帖子

4

主题

0

精华

大师

农村外出务工人员

F 币
607 元
贡献
311 点

新人勋章爱心勋章水王勋章元老勋章热心勋章

板凳
发表于 2017-11-6 10:28:53 | 显示全部楼层
换行符的问题,可以百度搜索“crlf”
(a,\) 意思是,输出一个字符(a),并且不换行(\)。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

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

GMT+8, 2024-5-5 14:10

Powered by Tencent X3.4

© 2013-2024 Tencent

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