Fortran 二进制文件读写
- 格式:pdf
- 大小:136.40 KB
- 文档页数:5
常见fortran错误1. Incrementally linked image--PC correlation disabled.!编译终止2. forrtl: severe (157): Program Exception - access violation!The program tried to read from or write to a virtual address for which it does not have the appropriate access. Try recompiling with the /check:bounds and /warn:argument_checking options set, to see if the problem is an out-of-bounds memory reference or a argument mismatch that causes data to be treated as an address.Other causes of this error include:Mismatches in C vs. STDCALL calling mechanisms, causing the stack to become corrupted References to unallocated pointers Attempting to access a protected (for example, read-only) address3 "forrtl: severe (64): input conversion error, unit 2, file D:\FORTRAN2\testi!文件testi正在读写,直到读写到2时错误。
举例:程序想读写整数,却碰到变量故终止。
4 error LNKZOOI : unresolved external symbol _ SN @ 4 fatal error LNKllZO : 1 unresolved externals! 出现了未指定的外部函数符号Sn 。
第六章在IDL中读写数据本章概要本章旨在介绍IDL中的常用的输入和输出程序。
IDL中的基本原则是:“只要有数据,就可以将其读进IDL”。
IDL没有格式要求,也没有特别要求在将数据带入IDL时对数据进行准备。
这使得IDL成为目前功能最强、最灵活的科学可视化分析语言。
具体来说,将学习:1.如何打开文件进行读写2.如何查找文件3.如何获得文件I/O的逻辑设备号4.如何获得机器的独立文件名5.如何读写ASCII或格式化的数据6.如何读写非格式化的或二进制数据7.如何处理大型数据文件8.如何读写通用的文件格式,如GIF和JEPG文件打开文件进行读写IDL中的所有输入和输出都是通过逻辑设备号完成的。
可以把一个逻辑设备设想为一个管道,这个管道连接着IDL和要读写的数据文件。
要从一个文件中读写数据,必须首先把一个逻辑设备号连接到一个特定的文件。
这就是IDL中三个Open命令的作用:openr 打开文件进行读。
openw 打开文件进行写。
openu 打开文件进行更新(也就是说,读和/或写)。
这三个命令的语法结构是完全相同的。
首先是命令名,后面是一个逻辑设备号和要与该逻辑设备号相连的文件名。
例如,将文件名temp596.dat和逻辑设备号20相连以便可以在此文件里面写入内容。
如下:OpenW, 20,‟temp596.dat‟将会看到Open命令更常用的书写方式。
例如,可能会看到类似于如下的IDL代码:OpenR, lun, filename此例中,变量lun保存了一个有效的逻辑设备号,变量filename代表一个机器特定的文件名,这个文件名将和此逻辑设备号联系起来。
注意,变量filename是一种机器特定的格式。
这意味着如果它含有特定的目录信息,它必须用本地机器的语法来表达。
而且它在某些机器(比如,UNIX机器)上具有大小写敏感性,因为在这些机器上文件名有大小写敏感性。
查找和选择数据文件IDL被广泛使用的原因之一,是IDL可以在许多不同的计算机操作系统中运行。
fortran中write的用法在Fortran编程语言中,write是一个很重要的指令,用于将数据输出到屏幕、文件或其他设备。
它的用法非常灵活,可以满足各种不同的需求。
首先,我们来了解一下write的基本语法。
在Fortran中,write的语法如下:```fortranwrite(format) [variable_list]```其中,format是一个控制写入输出的格式的字符串。
它用特定的格式指令来定义输出的样式,比如整数、浮点数、字符串等类型的输出。
variable_list是要输出的变量列表,可以是单个变量或多个变量。
下面是一些常见的write的例子:1. 简单的输出整数:```fortraninteger :: num = 10write(*, '(I4)') num```上面的代码将整数num的值以4位整数的格式输出到屏幕。
2. 输出浮点数:```fortranreal :: value = 3.14159write(*, '(F6.2)') value```上面的代码将浮点数value的值以6位宽度、保留2位小数的浮点数格式输出到屏幕。
3. 输出字符串:```fortrancharacter(10) :: name = 'Fortran'write(*, '(A)') name```上面的代码将字符串name的值以字符序列的格式输出到屏幕。
4. 输出到文件:```fortraninteger :: num = 10integer, parameter :: unit = 10open(unit, file='output.txt')write(unit, '(I4)') numclose(unit)```上面的代码将整数num的值以4位整数的格式输出到名为output.txt的文件中。
常见fortran错误1. Incrementally linked image--PC correlation disabled.!编译终止2. forrtl: severe (157): Program Exception - access violation!The program tried to read from or write to a virtual address for which it does not have the appropriate access. Try recompiling with the /check:bounds and /warn:argument_checking options set, to see if the problem is an out-of-bounds memory reference or a argument mismatch that causes data to be treated as an address.Other causes of this error include:Mismatches in C vs. STDCALL calling mechanisms, causing the stack to become corrupted References to unallocated pointers Attempting to access a protected (for example, read-only) address3 "forrtl: severe (64): input conversion error, unit 2, file D:\FORTRAN2\testi!文件testi正在读写,直到读写到2时错误。
举例:程序想读写整数,却碰到变量故终止。
4 error LNKZOOI : unresolved external symbol _ SN @ 4 fatal error LNKllZO : 1 unresolved externals! 出现了未指定的外部函数符号Sn 。
fortran runtime end of file在Fortran编程中,"End of File"是一个常见的错误,通常发生在尝试从一个文件读取数据,但是已经到达文件的末尾时。
当程序尝试读取超出文件末尾的数据时,就会触发这个错误。
为了避免这个错误,你可以在读取文件之前检查是否已经到达文件的末尾。
在Fortran中,你可以使用EOF函数来检查是否到达文件末尾。
EOF函数返回一个逻辑值,如果已经到达文件末尾,那么它返回.TRUE.,否则返回.FALSE.。
下面是一个简单的例子,演示了如何在读取文件时使用EOF函数:fortran复制代码PROGRAM ReadFileIMPLICIT NONEINTEGER :: iosCHARACTER(LEN=100) :: lineOPEN('myfile.txt', STATUS='OLD', IOSTAT=ios)IF (ios /= 0) THENPRINT *, 'Error opening file'STOPEND IFDO WHILE (.NOT. EOF(1))READ(1, *, IOSTAT=ios) lineIF (ios /= 0) EXITPRINT *, lineEND DOCLOSE(1)END PROGRAM ReadFile在这个例子中,程序打开一个名为'myfile.txt'的文件,并在一个循环中逐行读取文件的内容。
每次读取一行之前,它都会检查是否已经到达文件的末尾。
如果已经到达文件的末尾,那么EOF(1)将返回.TRUE.,循环将结束,程序将关闭文件并退出。
如果在读取过程中发生任何错误,程序也会退出。
fortranopen语句Fortran中的open语句用于打开文件,它是Fortran编程中非常重要的一个语句。
在本文中,我们将介绍Fortran中open语句的一些常见用法和参数。
1. 打开文件以供读取:open(unit=10, file='input.txt', status='old', iostat=ierr)这个open语句打开了名为input.txt的文件,并将其与逻辑单元10关联。
通过指定status='old',我们将文件以只读模式打开。
如果文件打开成功,ierr将被设置为0。
2. 打开文件以供写入:open(unit=20, file='output.txt', status='new', iostat=ierr)这个open语句打开了名为output.txt的文件,并将其与逻辑单元20关联。
通过指定status='new',我们将文件以写入模式打开。
如果文件打开成功,ierr将被设置为0。
3. 打开文件以供读取和写入:open(unit=30, file='data.txt', status='unknown', iostat=ierr, access='direct')这个open语句打开了名为data.txt的文件,并将其与逻辑单元30关联。
通过指定status='unknown',我们允许文件既可以读取又可以写入。
通过指定access='direct',我们指定了文件的访问方式为直接访问。
4. 打开文件以供追加写入:open(unit=40, file='log.txt', status='old', iostat=ierr, position='append')这个open语句打开了名为log.txt的文件,并将其与逻辑单元40关联。
VB实现二进制文件读写VB语言是一种面向对象的编程语言,拥有丰富的文件读写相关的类和方法,可以方便地进行二进制文件的读写操作。
下面是一个使用VB实现二进制文件读写的示例:在VB中,可以使用`BinaryReader`类读取二进制文件。
首先要打开要读取的文件,然后创建一个BinaryReader对象,最后使用Read方法读取文件内容。
以下是一个简单的二进制文件读取的示例代码:```vbDim filePath As String = "C:\path\to\file.bin"Using reader As New BinaryReader(File.Open(filePath, FileMode.Open))Dim bytes( As ByteWhile reader.PeekChar( <> -1bytes = reader.ReadBytes(1024) ' 每次读取1024字节'对读取的字节进行处理'...End WhileEnd Using```2.二进制文件写入同样地,VB也提供了`BinaryWriter`类来实现二进制文件的写入。
首先创建一个BinaryWriter对象,然后使用Write方法将字节写入文件。
以下是一个简单的二进制文件写入的示例代码:```vbDim filePath As String = "C:\path\to\file.bin"Using writer As New BinaryWriter(File.Open(filePath, FileMode.Create))Dim bytes( As Byte = {65, 66, 67, 68} ' 要写入的字节writer.Write(bytes) ' 将字节写入文件End Using```以上代码示例中,`FileMode.Open`用于打开已存在的文件并进行读取操作,`FileMode.Create`用于创建新文件并进行写入操作。
⼆进制格式保存⽂件np.save和np.load-Numpy数组的保存与读取⽅法1. 数组以⼆进制格式保存np.save和np.load是读写磁盘数组数据的两个主要函数。
默认情况下,数组以未压缩的原始⼆进制格式保存在扩展名为npy的⽂件中,以数组a为例1 2np.save("filename.npy",a) b = np.load("filename.npy")利⽤这种⽅法,保存⽂件的后缀名字⼀定会被置为.npy2. 存取⽂本⽂件使⽤ np.savetxt 和 np.loadtxt 只能读写 1 维和 2 维的数组np.savetxt:将数组写⼊以某种分隔符隔开的⽂本⽂件中np.loadtxt:指定某种分隔符,将⽂本⽂件读⼊到数组中⽂本⽂件中的每⼀⾏必须含有相同的数据。
loadtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0) fname要读取的⽂件、⽂件名、或⽣成器。
dtype数据类型,默认float。
comments注释。
delimiter分隔符,默认是空格。
skiprows跳过前⼏⾏读取,默认是0,必须是int整型。
usecols:要读取哪些列,0是第⼀列。
例如,usecols = (1,4,5)将提取第2,第5和第6列。
默认读取所有列。
unpack如果为True,将分列读取。
例如:np.savetxt(r'/media/dell/D/qcc/RandLA-Net_ceshi/data/semantic_kitti/dataset/sequences/00/velodyne/cc_0.xyz',pointcl,fmt="%.5f,%.5f,%.5f",delimiter='\n') fmt="%.5f,%.5f,%.5f"是要以浮点说保存数据,⼩数点后保留5位⼩数。
Delphi读写⼆进制⽂件⼆进制⽂件(也叫类型⽂件),⼆进制⽂件是由⼀批同⼀类型的数据组成的⼀个数据序列,就是说⼀个具体的⼆进制⽂件只能存放同⼀种类型的数据。
typeTMember = recordName : string[10];eMail : string[20];Posts : LongInt;end;var Members : array[1..50] of TMember;向磁盘存储信息之前我们需要定义⼀个⼆进制类型⽂件的变量名,下⾯的代码声明⼀个名为F的类型⽂件变量。
var F : file of TMember;在Delphi中,为了建⽴⼀个⼆进制⽂件,需要使⽤这样的语法:var SomeTypedFile : file of SomeType ;这个⽂件的基类型(SomeType)可以是标准类型(⽐如整型),也可以是数组或记录类型,但是不能为长字符串、动态数组、类、对象或者是⼀个指针。
var F : file of TMember;i : integer ;beginAssignFile(F,'Members.dat');Rewrite(F);tryfor i:= 1 to 50 do Write (F, Members[ i ]);finallyCloseFile(F);end;end;为了处理“Members.dat”⽂件记录的所有数据,必须使⽤如下形式的代码:var Member: TMemberF : file of TMember;beginAssignFile(F,'Members.dat');Reset(F);trywhile not Eof(F) do begin Read (F, Member);{这⾥可以对论坛成员信息进⾏相关处理}end;finallyCloseFile(F);end;end;⼆进制⽂件还可以使⽤标准的Seek过程实现随机访问,Seek过程可以指定⽂件当前位置的跳转。
Fortran 二进制文件读写【给新手】
2008-05-17 11:43:18| 分类: 胡说八道|字号 订阅 一些朋友总是咨询关于二进制文件的读写和转化。这里就我自己的理解说一说。
一).一般问题 二进制文件与我们通常使用的文本文件储存方式有根本的不同。这样的不同很难用言语表达,自己亲自看一看,理解起来会容易得多。因此,我推荐学习二进制文件读写的朋友安装一款十六进制编辑器。这样的编辑器有很多,在我们的 CVF 附带的集成开发环境下就可以(将二进制文件拖动到 IDE 窗口后松开)。Visual Studio 2005 也是可以的。(不过需要在 File 菜单下 Open,File) 另外推荐一款使用较多的软件,叫做 UltraEdit(以下简称 UE)。是很不错的文本编辑器,也能做十六进制编辑器使用。 为什么要用十六进制编辑器?而不用 2 进制呢?因为 2 进制实在太小,书写起来会很长,很不直观。而我们的计算机把 8 位作为一个字节。刚好 2 ** 8 = 256 = 16 ** 2。用 8 位 2 进制表达的数,我们用 2 个十六进制数据来表达,更直观和方便。
二).文件格式 所有文件,笼统意义上将可以区分为两类,一类是文本文件,一类是二进制文件。
1).文本文件 文本文件用记事本等文本编辑器打开,我们可以看懂上面的信息。所以使用比较广泛。通常一个文本文件分为很多很多行,作为数据储存时,还有列的概念。实际上,储存在硬盘或其他介质上,文件内容是线一样储存的,列是用空格或 Tab 间隔,行是用回车和换行符间隔。 以 ANSI 编码(使用较多)的文本文件来说,例如我们储存如下信息: 10 11 12 需要的空间是:3 行 × 每行 2 个字符 + 2 个回车符 + 2 个换行符 = 10 字节。文本文件储存数据是有格式,无数据类型的。比如 10 这个数据,并不指定是整型还是实型还是字符串。它有长度,就是 2,两个字节。储存时计算机储存它的 ASCII 码:31h,30h。(十六进制表示)。回车符是:0Dh,换行符:0Ah。 因此,这个数据储存是这样的: 31 30 0D 0A 31 31 0D 0A 31 32 (红色为回车符和换行符) 31h 30h 就是 10,31h 31h 就是 11,31h 32h 就是 12。因此我们也可以认为文本文件是特殊的二进制文件。 2).二进制文件 二进制文件,是无格式有数据类型的。比如上面的 10 11 12 三个数。但二进制文件没有行的概念。我们要紧凑地储存他们。(当然也可以中间加入一些空白的字节) 从数据类型上来说,我们首先考虑整型。如果把 10 11 12 当作 2 字长的整型。则 10 表示为:0Ah 00h。因为 0Ah 对应十进制 10。而后面的 00h 是空白位。2 字长的整型如果不足 FFh,也就是不足 255,则需要一个空白位。类似的:11 表示为 0Bh 00h,12 表示为 0Ch 00h。 当整型数据超过 255 时,我们需要 2 个字节来储存。比如 2748(ABCh),则表示为:BCh 0Ah。要把低位写在前面(BCh),高位写在后面(0Ah)。 当整型数据超过 65535 时,我们就需要 4 个字节来储存。比如 439041101(1A2B3C4Dh),则表示成:4Dh 3Ch 2Bh 1Ah。当数据再大时,我们就需要 8 字节储存了。 二进制文件的实型数据也有字节长度的区分,比如 4 字长,8 字长。但实型数据的长度并不仅仅代表它的表达的范围,更多的代表精度。所以,8 字长的我们又称为双精度。关于实型数据如何储存为 2 进制。则有很多套规则。现在都广泛使用的是 IEEE 标准浮点格式。关于这样的规则,我还正在了解,比较麻烦。就不多说了。在这里也没有必要了解。 二进制文件也可以储存字符型数据,储存方法和文本文件一样。都是使用 ASCII 编码储存的。所以我们用记事本打开某些二进制文件时,也能看到一些有意义的字符串。(无意义的乱码我们可以认为是整型或实型,不过记事本程序当作字符来解释,因此造成了乱码)
三).使用二进制文件的好处 为什么要使用二进制文件。原因大概有三个: 第一是二进制文件比较节约空间,这两者储存字符型数据时并没有差别。但是在储存数字,特别是实型数字时,二进制更节省空间,比如储存 Real*4 的数据:3.1415927,文本文件需要 9 个字节,分别储存:3 . 1 4 1 5 9 2 7 这 9 个 ASCII 值,而二进制文件只需要 4 个字节(DB 0F 49 40) 第二个原因是,内存中参加计算的数据都是用二进制无格式储存起来的,因此,使用二进制储存到文件就更快捷。如果储存为文本文件,则需要一个转换的过程。在数据量很大的时候,两者就会有明显的速度差别了。 第三,就是一些比较精确的数据,使用二进制储存不会造成有效位的丢失。
四).二进制文件的储存方式 列举一个二进制文件如下: 00000000h: 0F 01 00 00 0F 03 00 00 12 53 21 45 58 62 35 34 ; .........S!EXb54 00000010h: 41 42 43 44 45 46 47 48 49 47 4B 4C 4D 4E 4F 50 ; ABCDEFGHIGKLMNOP 这里列出的是在 UltraEdit(UE) 里看到的东西。其实只有红色部分是文件内容。前面的是 UE 加入的行号。后面的是 UE 尝试解释为字符型的参考。 这个文件一共有 32 字节长。显示为两列,每列 16 个字节。实际上,这仅仅是 UE 的显示而已。真实的文件并不分行。仅仅知道这个文件的内容,如果我们没有任何说明的话,是不能看出任何有用信息的。 下面我规定一下说明:我们认为,前 4 个字节是一个 4 字节的整型数据(0F 01 00 00 十六进制:10Fh 十进制:271)。这 4 个字节之后的 4 个字节是另一个 4 字节的整型数据(0F 03 00 00 十六进制:30Fh 十进制:783)。其后的 4 个字节(12 53 21 45 )表示一个 4 字节的实型数据:2.5811919E+3。再其后的 4 个字节(58 62 35 34)表示另一个 4 字节的实行数据:1.6892716E-7。而只后的 16 个字节(41 42 43 44 45 46 47 48 49 47 4B 4C 4D 4E 4F 50)我们认为是 16 个字节的字符串(ABCDEFGHIGKLMNOP) 实际上,二进制文件只是储存数据,并不写明数据类型,比如上面的第 9 字节到第 16 字节(12 53 21 45 58 62 35 34),我们刚才认为是 2 个 4 字节的实型,其实也可以认为是 8 个字节的字符型( S!EXb54)。而后面的 16 个字节的字符串(ABCDEFGHIGKLMNOP),我们也可以认为是 2 个 8 字节的整型,或者 4 个 4 字节的整型,甚至 2 个 8 字节的实型,4 个 4 字节的实型,等等等等。 因此,面对一个二进制文件,我们不能准确地知道它的含义,我们需要他的数据储存方式的说明。这个说明告诉我们第几个字节到第几个字节是什么类型的数据,储存的数据是什么含义。否则的话,我们只能猜测,或者无能为力。
五).如何使用语句操作二进制文件 我们将上面的那个二进制文件保存为:TestBin.Bin 来举例。 读取和写入二进制其实是两个很类似的操作,了解了其中之一,另一个也就不难了。 二进制文件我们通常使用直接读取方式,Open 语句可以写为: Open( 12 , File = 'TestBin.Bin' , Access = 'Direct' , Form = 'Unformatted' , RecL = 4 ) 上面的 Access 表示直接读取方式,Form 表示无格式储存。比较重要的是 RecL 。我们读取数据时,是用记录来描述单位的,每一次读入或写入是一个记录。记录的长度在 Open 时就确定下来,以后不能改变。如果需要改变,只能 Close 以后再此 Open。 记录长度在某些编译器下表示读取的 4 字节长度的倍数,规定为 4 表示记录长度为 16 字节。有些编译器下就直接表示记录的字节数,规定为 4 则表示记录长度为 4 字节。这个问题需要参考编译器手册。在 VF 系列里,这个值是前面一个含义。可以通过设置工程属性的 Fortran,Data,Use Bytes as RECL= Unit for Unformatted Files 来改变,使之成为后一个含义。在命令行模式下,则使用 /assume:byterecl 这个编译选项。 确定 RecL 大小是我们需要做的事情,一般来说,不适合太大,也不适合太小。还需要结合数据储存方式来考虑。太小的话,我们需要执行读写的次数就多,太大的话,我们就不方便操作小范围的数据。 有时候我们甚至会分多次来读取数据,每一次的 RecL 都不同。对于上面的 TestBin.Bin 文件来说,它比较简单,我以 16 字节长度和 8 字节长度两种读取方式来演示,你甚至可以一次 32 个字节长度全部读完: (1)RecL = 4 【记录长度 16 字节】 Program main Implicit None Integer*4 :: iVar1 , iVar2 Real*4 :: rVar1 , rVar2 Character(Len=16) :: cStr Open( 12 , File = 'TestBin.Bin' , Access = 'Direct' , Form = 'Unformatted' , RecL = 4 ) Read( 12 , Rec = 2 ) cStr Read( 12 , Rec = 1 ) iVar1 , iVar2 , rVar1 , rVar2 Write( * , * ) cStr Write( * , * ) iVar1 , iVar2 , rVar1 , rVar2 Close( 12 ) End Program main 这里的 Open 里指定了 RecL = 4(记录长度是 16 字节)。 第一个 Read 语句,直接读取第二笔记录(也就是第 17 字节到第 32 字节)。读取出的 cStr = "ABCDEFGHIGKLMNOP"。 第二个 Read 语句,返回来读取第一笔记录(也就是前面 16 个字节)。读取出的数据分别放入 4 个 4 字节的变量。(其中前面两个是整型,后面两个是实型) 输出结果为: ABCDEFGHIGKLMNOP 271 783 2581.192 1.6892716E-07 看到这个结果,就说明我们成功了。 同时我们可以看到,第一个语句,我们直接跳到第二条记录读取,并没有读取第一条。这就是直接读取数据的方便。有时候我们根本不需要某些数据,这时候,我们可以直接跳到某一条记录上。这个记录甚至可以是我们实现算出来的变量。比如: iRec = ( a + b ) / C Read( 12 , Rec = iRec ) cStr 实现我们储存了 100 天的数据,我们只需要第 21 天的数据,我们怎么办?在顺序读取时,我们可能会开辟一个 100 元素的数组,或者循环执行 20 次空白的读取。但是在直接读取时,我们只需要执行一句 Read( 12 , Rec = 21 )。这是多么的方便。(直接读取和顺序读取虽然于文本文件和二进制文件没有直接的关联,但是文本文件通常用顺序读取,而二进制文件通常用直接读取。这是他们的性质决定的。) (2)RecL = 2【记录长度为 8 字节】 Program main Implicit None Integer*4 :: iVar1 , iVar2 Real*4 :: rVar1 , rVar2 Character(Len=16) :: cStr