Fortran Coder

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

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

[复制链接]

17

帖子

8

主题

0

精华

熟手

F 币
120 元
贡献
65 点
跳转到指定楼层
楼主
发表于 2017-10-30 12:14:12 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
小弟最近在做一个文本文件转化为二进制文件的问题,希望可以将文件的大小实现压缩,然后需要的时候再转为文本文件读取,现在这个文件是这样的,就是前面的19行均为长度不一得字符串,后面是几行小数,具体小数的行数就是第19行字符串中的整数,如此循环,我编了一个程序,编译没什么问题,但是一运行就卡着半天不动了,不知道问题出在哪了,我的思路是想先把前面19行循环读取,然后再把第19行的字符串转化为整数,然后循环读取小数,但是这样的话出现很多空格,文件反而更大了,希望各位大佬能不吝赐教。
[Fortran] 纯文本查看 复制代码
program jack01
    implicit none
    
    character(len = 66) buffer
    integer :: num = 0
    real(kind = 4) :: a, b
    integer :: status = 0
    integer countera,counterb
    integer, parameter :: lines = 19
    integer :: r = 1
    logical alive
    
    inquire(file = 'new.txt',exist = alive)
    if(alive)then
        !打开输入输出文件
        open(unit = 12, file = 'new.txt')
        open(unit = 13, file = 't.bin', access = 'direct', form = 'unformatted', recl = 20 )
        do while(.true.)
            !转存前面19行的内容
            do  countera = 1, lines, 1
                read(14, fmt = "(A66)",iostat = status) buffer
                if(status /= 0) exit
                write(15, rec = r) buffer
                r = r + 1
            end do
            countera = 1
           
            !转存实数部分的内容
            do  counterb = 1, num, 1
                read(14, *, iostat = status) a, b
                if(status /= 0) exit
                write(15, rec = r) a, b
                r = r + 1
            end do
            counterb = 1
        end do
    else
        write(*,*)'new.txt',"does not exist"
    end if
    
    !关闭输入输出文件
    close(12)
    close(13)
    stop
    end

new.txt

61.56 KB, 下载次数: 10

分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

17

帖子

8

主题

0

精华

熟手

F 币
120 元
贡献
65 点
沙发
 楼主| 发表于 2017-10-30 14:31:10 | 显示全部楼层
pasuka 发表于 2017-10-30 12:34
为啥不能先把所有的txt文件打包成单个zip、gz格式的压缩文件,然后按照规则抽取需要的txt文件呢? ...

导师要求的,要我那这个先练习练习,然而一直报错

17

帖子

8

主题

0

精华

熟手

F 币
120 元
贡献
65 点
板凳
 楼主| 发表于 2017-10-30 16:36:19 | 显示全部楼层
楚香饭 发表于 2017-10-30 12:46
你这种问题不太容易用二进制存储,因为每个 block 的文本头部都不一样长。
后面用二进制读取的时候,不知道 ...

万分感谢,是可以转出来了。不过就是转换回去的时候如果用流文件的处理是要读取指定字节数的,但是这边的头文件区域的字节数都是不固定的,所以之前我在一开始转的时候想把他弄成一条条的记录去做,然后转成文本文件的时候直接一条条的读,但是好像这样的话弄出来的二进制文件反而更大了。

17

帖子

8

主题

0

精华

熟手

F 币
120 元
贡献
65 点
地板
 楼主| 发表于 2017-10-30 16:38:42 | 显示全部楼层
pasuka 发表于 2017-10-30 14:37
gzip就是一种无损压缩的二进制存储格式
https://en.wikipedia.org/wiki/Gzip
https://en.wikipedia.org/wi ...

谢谢帮助,这个很有用。我会继续学习的,因为现在是刚学习Fortran阶段,所以老师也是希望我通过这个练习熟悉熟悉Fortran语言,可能后续的课题也会使用。

17

帖子

8

主题

0

精华

熟手

F 币
120 元
贡献
65 点
5#
 楼主| 发表于 2017-11-6 09:39:37 | 显示全部楼层
楚香饭 发表于 2017-10-31 08:36
可以把文本的大小也写在二进制文件里。

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

谢谢您,我拜读了一下您的代码,并且也跑了一下,成功了,但是任然有一些地方不是很明白 character(len = *) , parameter :: crlf = char(z'd') // char(z'a')!//换行符,不同操作系统不一样,这个是指从一个换行符到另外一个换行符的长度吗,但是这个换行符我在书上和网上一直没找到,还有就是 Write(14,'(a,\)') text里面的'(a,\)'我也不是很清楚,查了一些资料但是始终还是没太明白

17

帖子

8

主题

0

精华

熟手

F 币
120 元
贡献
65 点
6#
 楼主| 发表于 2018-3-7 14:25:29 | 显示全部楼层
楚香饭 发表于 2017-11-6 10:28
换行符的问题,可以百度搜索“crlf”
(a,\) 意思是,输出一个字符(a),并且不换行(\)。 ...

请问Fortran里面的crlf为什么可以被定义为character(len=*) , parameter :: crlf = char(z'd') // char(z'a')啊,我在网上看了好像是0x0A,0x0D,但是为什么Fortran里面可以这么表示呢?
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

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

GMT+8, 2024-5-5 11:38

Powered by Tencent X3.4

© 2013-2024 Tencent

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