使用文本文件txt 进行数据存取的技巧总结相当使用文本文件(.txt)进行数据存取的技巧总结由于本帖内容较多,部分转自他人的心得,因此,凡转贴的地方仅用"--转--"标注,原作者略去,在此对所有原作者表示感谢!特别说明:由于大家在I/O存取上以txt文件为主,且读取比存储更麻烦(存储的话fwrite,fprintf基本够用),因此下面的讨论主要集中在"txt文件的读取"上。
除了标注了"转"之外,其余心得均出于本人经验之结果,欢迎大家指正、补充。
一.基本知识:--转--1.二进制文件与文本文件的区别:将文件看作是由一个一个字节(byte)组成的,那么文本文件中的每个字节的最高位都是0,也就是说文本文件使用了一个字节中的七位来表示所有的信息,而二进制文件则是将字节中的所有位都用上了。
这就是两者的区别;接着,第二个问题就是文件按照文本方式或者二进制方式打开,两者会有什么不同呢?其实不管是二进制文件也好,还是文本文件也好,都是一连串的0和1,但是打开方式不同,对于这些0和1的处理也就不同。
如果按照文本方式打开,在打开的时候会进行translate,将每个字节转换成ASCII码,而以按照二进制方式打开的话,则不会进行任何的translate;最后就是文本文件和二进制文件在编辑的时候,使用的方式也是不同的。
譬如,你在记事本中进行文本编辑的时候,你进行编辑的最小单位是字节(byte);而对二进制文件进行编辑的话,最小单位则是位(bit),当然我们都不会直接通过手工的方式对二进制文件进行编辑了。
从文件编码的方式来看,文件可分为ASCII码文件和二进制码文件两种:ASCII文件也称为文本文件,这种文件在磁盘中存放时每个字符对应一个字节,用于存放对应的ASCII码。
例如,数5678的存储形式为:ASCII码:00110101 00110110 00110111 00111000↓↓↓↓十进制码:5 67 8共占用4个字节。
ASCII码文件可在屏幕上按字符显示,例如源程序文件就是ASCII文件,用DOS命令TYPE可显示文件的内容。
由于是按字符显示,因此能读懂文件内容。
二进制文件是按二进制的编码方式来存放文件的。
例如,数5678的存储形式为:00010110 00101110只占二个字节。
二进制文件虽然也可在屏幕上显示,但其内容无法读懂。
C系统在处理这些文件时,并不区分类型,都看成是字符流,按字节进行处理。
输入输出字符流的开始和结束只由程序控制而不受物理符号(如回车符)的控制。
因此也把这种文件称作"流式文件"。
2.文本模式(textmode)和二进制模式(binarymode)有什么区别?流可以分为两种类型:文本流和二进制流。
文本流是解释性的,最长可达255个字符,其中回车/换行将被转换为换行符"\n",(如果以"文本"方式打开一个文件,那么在读字符的时候,系统会把所有的"\r\n"序列转成"\n",在写入时把"\n"转成"\r\n")。
二进制流是非解释性的,一次处理一个字符,并且不转换字符。
注:\n一般会操作系统被翻译成"行的结束",即LF(Line-Feed)\r会被翻译成"回车",即CR(Cariage-Return)对于文本文件的新行,在UNIX上,一般用\n(LF)来表示,Mac上用\r(CR)来表示,Windows上是用\n\r(CR-LF)来表示。
通常,文本流用来读写标准的文本文件,或者将字符输出到屏幕或打印机,或者接受键盘的输入;而二进制流用来读写二进制文件(例如图形或字处理文档),或者读取鼠标输入,或者读写调制解调器。
如果用文本方式打开二进制文件,会把"0D 0A"自动变换成"\n"来存在内存中。
写入的时候反向处理。
而二进制方式打开的话,就不会有这个过程。
但是,Unicode/UTF/UCS格式的文件,必须用二进制方式打开和读写。
---上述基础其实大可以略过,简言之,对用户来说:在matlab中存储成为二进制还是文本文件取决于fopen的方式,如果用wt,则存储为文本文件,这样用记事本打开就可以正常显示了;如果用w则存储为二进制文件,这样用记事本打开会出现小黑方块,要正常显示的话,可以用写字板或UltraEdit等工具打开。
二.Matlab的I/O文件操作使用技巧和总结:1.Matlab支持的I/O文件(对应"取/存"操作)类型:(所有文件I/O程序不需要特殊的工具箱)(注:从上表可以看到,matlab不支持doc格式的文档存取(因为doc文档包含很多格式控制符),请改用txt或者dat格式)2.Matlab的I/O文件指南:以下是部分对应的中文译文:--转--本技术支持指南主要处理:ASCII,binary,and MAT files.要得到MATLAB中可用来读写各种文件格式的完全函数列表,可以键入以下命令:help iofun MATLAB中有两种文件I/O程序:high level and low level.High level routines:包括现成的函数,可以用来读写特殊格式的数据,并且只需要少量的编程。
Low level routines:可以更加灵活的完成相对特殊的任务,需要较多的额外编程。
High level routines包括现成的函数,可以用来读写特殊格式的数据,并且只需要少量的编程。
举个例子,如果你有一个包含数值和字母的文本文件(text file)想导入MATLAB,你可以调用一些low level routines自己写一个函数,或者是简单的用TEXTREAD函数。
使用high level routines的关键是:文件必须是相似的(homogeneous),换句话说,文件必须有一致的格式。
下面的段落描述一些high level fileI/O routines并给出一些例子帮助理解概念。
LOAD/SAVE主要的high level file I/O routines是LOAD和SAVE函数。
LOAD可以读MAT-file data或者用空格间隔的格式相似的ASCII data.SAVE可以将MATLAB变量写入MAT-file格式或者空格间隔的ASCII data。
大多数情况下,语法相当简单。
下面的例子用到数值由空格间隔的ASCII filesample_file.txt:1 54 16 85 43 26 86 84 32 190 78 76 59 81 23 Example:用LOAD and SAVE读写数据CODE:%Load the file to the matrix,M:M=load('sample_file.txt')%Add 5to M:M=M+5%Save Mto a.mat file called'sample_file_plus5.mat':save sample_file_plus5 M%Save Mto an ASCII.txt file called'sample_file_plus5.txt':save sample_file_plus5.txt M-ascii UIGETFILE/UIPUTFILE UIGETFILE/UIPUTFILE是基于图形用户界面(GUI)的。
会弹出对话框,列出当前目录的文件和目录,提示你选择一个文件。
UIGETFILE让你选择一个文件来写(类似Windows'另存为'选项?)。
用UIGETFILE,可以选择已存在的文件改写,也可以输入新的文件名。
两个函数的返回值是所选文件名和路径。
Example:用UIGETFILE从当前目录选择一个M-file CODE:%This command lists all the M-files in the current directory and%returns the name and path of the selected file[fname,pname]=uigetfile('*.m','Sample Dialog Box')注意:UIGETFILE一次只能选择一个文件。
UIIMPORT/IMPORTDATA UIIMPORT是一个功能强大,易于使用的基于GUI的high level routine,用于读complex data files。
文件也必须是homogeneous。
IMPORTDATA形成UIIMPORT的功能,不打开GUI。
可以将IMPORTDATA用于函数或者脚本中,因为在函数或者脚本中基于GUI的文件导入机制并不理想。
下面的例子用到包含几行文件头和文本、数值数据的文件'sample_file2.txt':This is afile header.This is file is an example.col1 col2 col3 col4 A1 4612.000 B1 4613.000 C1 4614.000 D14615.000 Example:Using IMPORTDATA to read in afile withheaders,text,and numeric data CODE:%This reads in the file'sample_file2.txt'and creates a%structure Dthat contains both data and text data.%Note the IMPORTDATA command specifies awhite space%as the delimiter of the file,but IMPORTDATA can usually%detect this on its own D=importdata('sample_file2.txt','')%原文有误?D=importdata('sample_file2.txt')可以通过访问结构D的数据和文本域,来看结构D中的真实值,例如输入:data=D.data text=D.textdata可以用UIIMPORT读同一个文件并得到同样的结构.注意:对于ASCII data,你必须检验导入向导正确的识别了列分隔符。