Fortran 实用编程 系列视频教程 Fortran Coder 研讨团队 http://www.fcode.cn
关于 Fortran Coder Fortran Coder 始于2006年,是一个以科学计算编程为主题的非盈利性研讨团体。大多数由各行业高等学府学生,研究人员及生产一线的工作人员组成。 研讨内容涉及:Fortran77/90/95/2003/2008语法规范,各平台32位及64位编译器,IMSL,MKL,Lapack 等数学函数库,MPI,OpenMP,Coarray 并行及高性能计算,winteracter / DisLin / Matfor / GTKFortran 等绘图及界面库。
关于本套视频 本套视频以解决实际问题为主要目的,旨在为您解答课本上较少涉及到的实际问题。通过本套视频,您会更容易了解: 如何查找错误?如何解决错误? 如何学习 Fortran2003 和 Fortran2008 语法? 如何用最通俗易懂的写法解决实际问题? 如何看懂别人的优秀代码并为自己所用?如何让自己的代码更优美、更普适? 本套视频由 Fortran Coder 研讨团队录制,供所有 Fortran 程序员和学习者免费自由的观看,您可随意的传播它。但请保证视频完整性。 我们将会不定期的更新本套视频,请持续关注我们的网站、QQ群! 同时,如果您对 Fortran 相关有自己的见解,并愿意通过录制视频的方式与其他人分享,请联系我们!
上节要点回顾 文件只有两种:文本文件和二进制文件,这是文件的本质 fortran读取文件有三种方式:顺序、直接、流文件读取 因此,组合以后以后,一共 2*3=6 种 读写文件用到 Open/Read/Write/Close 四个语句 Read读取时尽量采样表控格式(*) 顺序读取需从前往后依次读取,直接读取可以跳转,但要求每记录(行)的长度一致。
语法之文件读写(下) 第十一讲 讲解人:雪球 gao@fcode.cn http://www.fcode.cn 讨论QQ群:2338021 基础篇 第十一讲 语法之文件读写(下) 讲解人:雪球 gao@fcode.cn http://www.fcode.cn 讨论QQ群:2338021
目 录 1 顺序读写无格式文件 2 直接读写无格式文件 3 流文件读写无格式文件 4 其他问题
顺序读写无格式文件 无格式文件(二进制文件),用于机器阅读,人类读懂较困难。 但是,它的格式与内存一样。因此是简单的复制到文件里,速度非常快! 非常适合: 大量的数据、中间数据、不希望普通用户看懂和随意更改的数据。 (SEGY、netcdf、bmp 、surfer grid 等都是二进制文件) 在了解二进制文件前,强烈建议安装一款“十六进制编辑器”软件。 用它,可在一定程度上“读懂”二进制文件(前提是你了解这个文件的格式) 本期资料里,附送一款 MiniHex 的绿色软件,可以打开任何二进制文件。
顺序读写无格式文件 顺序写入无格式文件,以记录为基本单元,读写过程分若干笔记录: 每次一笔记录,在记录前后各多出4个字节,用来记录本次写入的长度。 顺序读取时,通过这4个字节知悉当前记录的长度。
顺序读写无格式文件 我们再读取此文件时,程序会首先读入前 4 个字节,获得本笔记录的长度。 随后读入后 4 个字节,以验证是否与前 4 个字节相同(如不同则报错) 最后,把中间的字节按顺序,读取到变量列表里。
顺序读写无格式文件 因为有这个特殊的前后4字节,所以, 用 Fortran 顺序写入的文件,尽量还是用 Fortran 顺序读取。 用其他方式也可以读取顺序写入的文件,但会比较罗嗦和繁杂。 即: 只用 fortran,可以用顺序读写。 与其他软件、语言交互,通常不使用顺序读写。
目 录 1 顺序读写无格式文件 2 直接读写无格式文件 3 流文件读写无格式文件 4 其他问题
直接读写无格式文件 直接读写无格式文件,也以记录为基本单元,读写过程分若干笔记录: 但每一笔记录的长度,是固定的,在 Open 时指定。 在某些编译器上RecL 的含义是多少个 4 字节,而不是多少字节
直接读写无格式文件 直接读写无可以随便跳转到任何整记录读写,也可以一边读一边写。 读取时,不一定按照写入时候的顺序。
直接读写无格式文件 直接读写无可以随便跳转,自定义顺序,因此读写比较灵活。 但要求每个记录的长度一样,且Open以后就无法改变。 对于数据结构比较混乱(有2字节,有4字节,有8字节)的文件,读取不方便。 很多时候不得不多次Open、Close。用不同的RecL来读写不同长度的数据部分。 在以前,我们有一些技巧,来实现一次读取。 例如 Equivalence 语句,让不同长度的数据共享内存 就可以读写一个,而得到另一个。 然而,现在有了流文件方式,就不再推荐这种奇淫巧计了。 或者使用 MvBits 等函数对内存中的个别位进行移动
直接读写无格式文件 下面我们看一个直接读写 Goldensoft Surfer *.grd 文件的例子: 资料中有 fcode_test.grd,它是一个 6*10 的网格化文件 内容 类型 数值 长度 标记 character(len=4) DSBB 4 M、N integer(kind=2) 6 、 10 2*2 MinX 、MaxX real(kind=8) -2.0d0、3.0d0 8*2 MinY 、MaxY -4.0d0、5.0d0 MinZ 、MaxZ 0.0d0、5.83d0 Grid( M , N ) real(kind=4),dimension(m,n) 数组 4*6*10 共296字节
直接读写无格式文件 直接读写,理论上可读写任何文件。但对于长度不一的数据,会比较繁琐。 因此,它更适合读写那些:大量的,长度相同的, 或纯粹的数组。 在Fortran2003以前,它是读取二进制文件的唯一选择。 我们曾经用它开发过读写 SEGY 的代码,其逻辑复杂性不言而喻。 在 Visual Fortran 系列编译器上,还扩展有 binary 方式的读写。 其类似顺序读写,但没有前后4字节的表征。因此也比较灵活。但它是扩展语法,不规范
目 录 1 顺序读写无格式文件 2 直接读写无格式文件 3 流文件读写无格式文件 4 其他问题
流文件读写无格式文件 流文件,是 Fortran2003 的新语法!它完胜前 2+1 种读取方式! 它允许自由控制读写位置,自动判断本次读写的长度!强烈推荐!
流文件读写无格式文件 流文件,打开时,不指定 recl,打开后,读取位置自动在文件开始处。 执行 read 语句时,不指定 rec,读取长度 L 根据后面的变量表自动计算。 读取后,读取位置自动向后移动 L 个字节。一切都是自动完成的。
流文件读写无格式文件 除了可以自动判断位置和长度之外,流文件也允许随意跳转。 如上,我们只想读取 m,n 可直接跳转到第 5 字节读取,而不读取 DSBB 也可以查询当前读取的位置: 查询以后,可以跳过一定的字节(如32)继续读取:
流文件读写无格式文件 我们可以用一个派生类型 type 来定义头部信息,之后一次读取整个头部。 尤其对于类似 SEGY 这种有多个头部(道头)的文件来说,非常方便。
流文件读写无格式文件 流文件读写非常方便,它甚至可以方便的读取“顺序写入的二进制文件”。
流文件读写无格式文件 小结: 二进制文件的读写,一定是建立在知晓文件格式的前提下。(猜测?) 准备并学习一款十六进制编辑器,对二进制文件的读写非常有用。 流文件方式是万能的,能方便的读写任何二进制文件。 但对于某些非常规则的纯粹的数组,直接读取方式效率最高。 一些老代码生成的顺序写入的文件,还是可以用顺序方式读写。 对于 Visual Fortran 扩展的 binary 方式,能读懂就可以,最好自己不要用。
目 录 1 顺序读写无格式文件 2 直接读写无格式文件 3 流文件读写无格式文件 4 其他问题
Open( FID , File = "文件名" , convert="BIG_ENDIAN" ) 其他问题 关于字节序: 对于超过1个字节的数据类型,如 integer , real 占有 4 个字节。 那么就存在 4 个字节的存储顺序的问题。这就是字节序 Open( FID , File = "文件名" , convert="BIG_ENDIAN" ) Little-endian Big-endian
流文件读写无格式文件 关于文件路径的问题: Fortran 标准语法中,并没有规定任何文件夹(目录/路径)的问题。 Open 语句的 File 子句,是传递给操作系统(系统调用),因此,一般可以使用带(绝对或相对)路径的文件名 Open( 12 , File = "subfolder\filename.ext" ) ! windows Open( 12 , File = "D:\dir\subdir\filename.ext" ) ! windows Open( 12 , File = "/etc/passwd" ) ! linux Open( 12 , File = "../../otherdir/filename.ext" )! linux
流文件读写无格式文件 关于文件路径的问题: 如果不带任何路径,则被认为是当前路径(working directory) 如果带相对路径,则以当前路径为基准。 通过命令行执行时,当前路径一般在提示符上(或 pwd 命令查看) 直接双击运行,当前路径在 exe 所在的文件夹 通过 IDE 方式运行,当前路径一般在工程所在文件夹。 一些 IDE 还允许设置当前路径(只对IDE方式运行有效)。
流文件读写无格式文件 关于文件路径的问题: 程序中可以通过一些方式,动态的更改当前路径 不同的编译器都有类似的扩展 IVF : ChangeDirQQ ; gfortran : ChDir ; 有的编译器还允许获得当前路径 IVF / gfortran : GetCWD 我们来看一个演示
感谢收看! Fortran Coder Group http://www.fcode.cn 下一讲:语法内的标准函数 敬请关注 & 期待 还有疑问?请联系我们 Fortran Coder Group http://www.fcode.cn