-
matlab
中使用文本文件
(.txt)
p>
进行数据存取的技巧总结
由于本帖内容较多,部分转自他人的心得,因此,凡转贴的地
方仅用
“
----
转
< br>----
”
标注,原作者略去,
在此对所有原作者表示感谢!
特别说明:
由于大家在
I/O
存取上以
txt
文件为主,
且读取比存储更麻
烦
(存储的话
fwrite,
fprintf
基
本够用)
,
因此下面的讨论主要集中在
“
txt
文件的读取
”
上。
除
了标注了
“
转
”
之外,
其余心得均出于本人
经验之结果,欢迎大家指正、补充
。
一
.
基本知识:
-----------
---------------------------------------
转
--------------------------------------
--------------------------------------------------
-------
1.
二进制文件与文本文件的区别:
将文件看作是由一个一个字节
(byte)
组成的,
那么文本文件中的每个字节
的最高位都是
0
,也就是说
文本文件使
用了一个字节中的七位来表示所有的信息,而二进制文件则是将字节中的所有位都用上了。
这就是两者的区别;
接着,
第二个问题就是文件按照文本方式
或者二进制方式打开,
两者会有什么不同
呢?其实不管是二进制
文件也好,还是文本文件也好,都是一连串的
0
和
1
,但是打开方式不同,对于
这些
< br>0
和
1
的处理也就不同。如果按
照文本方式打开,在打开的时候会进行
translate
,将
每个字节转换
成
ASCII
码,而以按
照二进制方式打开的话,则不会进行任何的
translate
;最后就是文本文件和二进
制文件在编辑的时候,
使用的方式也
是不同的。
譬如,
你在记事本中进行文本编辑的时候,
你进行编辑
的最小单位是字节
(byte)
p>
;而对二进制文件进行编辑的话,最小单位则是位
(bit)
,当然我们都不会直接
通过手工的方式对二进制文件进行编辑了。
p>
从文件编码的方式来看,文件可分为<
/p>
ASCII
码文件和二进制码文件两种:
ASCII
文件也称为文本文件,这种文件在磁盘中存放时每个
字符对应一个字节,用于存放对应的
ASCII
码。例如,数<
/p>
5678
的存储形式为:
ASCII
码:
00110101 00110110 00110111 00111000
↓
↓
↓
↓
十进制码:
5
6
7
8
共
占用
4
个字节。
ASCII
码文件可在屏幕上按字符显示,例如源程序文件就是
ASCII
文件,用
DOS
命令
TY
PE
可显示文件的内容。由于是按字符显示,因此能读懂文件内容。
二进制文件是按二进制的编码方式来存放文件的。
p>
例如,
数
5678
的存储形式为:
00010110 00101110
只
p>
占二个字节。二进制文件虽然也可在屏幕上显示,但其内容无法读懂。
C
系统在处理这些文件时,并不
区分类型,
< br>都看成是字符流,
按字节进行处理。
输入输出字符流的开
始和结束只由程序控制而不受物理
符号
(
如回车符
)
的控制。因此也把这种文件称作
< br>“
流式文件
”
。
2.
文本模式
(textmode)
和二进制模式
(binarymode)
有什么区别
?
流可以分为两种类型:
文本流和二进制流。
文本流是解
释性的,
最长可达
255
个字符,
p>
其中回车
/
换行将
被转换为换行符
“
n
”
,
(如果以
文本
方式打开一个文件,那么在读字符的时候,系统会把所有的
< br>
序列转成
,在写入时把
转成
)
。二进制流是非解释性的,一次处理一个字符,并且不转换
字符。
注:
n
一般会操作系统被翻译成
行的结束
,即
LF(Line-Feed)
r
会被翻译成
回车
,即
C
R(Cariage-Return)
对于文本文件的新行,在
UNIX<
/p>
上,一般用
n(LF)
来表示,
Mac
上用
r(CR)
来表示,
Windows
上是用
nr(CR-
LF)
来表示。
通常,
文本流用来读写标准的文本文
件,
或者将字符输出到屏幕或打印机,
或者接受键盘的输入;<
/p>
而二
进制流用来读写二进制文件
(
例如图形或字处理文档
)
,或者读取鼠标输入
,或者读写调制解调器。如果
用文本方式打开二进制文件,会把
“
0D 0A
”
自动变换成
“
n
”
来存在内存中。写
入的时候反向处理。而二
进制方式打开的话,就不会有这个过程。但是,
Unicode/UTF/UCS
格式的文件,必须用二进制方式打
开和读写。
----------------
--------------------------------------------------
--------------------------------------------------
------
------------------------
上述基础其实大可以略过,
简言之,
对用户来说:
在
matlab
p>
中存储成为二进制还是文本文件取决于
fopen
< br>的方式,如果用
wt
,则存储为文本文件,这样用记事本
打开就可以正常显示了;如果用
w
则存
储为二进制文件,这样用记事本打开会出现小黑方块,要正常显示的话,可以用写字板或
UltraEdit
等
工具打开。
二
. Matlab
的
I/O
文件操作使用技巧和总结
:
1. Matlab
p>
支持的
I/O
文件(对应
< br>“
取
/
存
”
操作)类型:
(所有文件
I/O<
/p>
程序不需要特殊的工具箱)
/support/tech-notes/1100/
<
/p>
(注:从上表可以看到,
matlab
不
支持
doc
格式的文档存取(因为
do
c
文档包含很多格式控制符)
,请
改用
txt
或者
dat
格式)
2. Matlab
的
I/O
文件指南:
< br>
/support/tech-notes/1600/
以下是部分对应的中文译文:
---
--------------------------------------------------
---------
------------------------------
---------------------------------------------
本支持指南主要处理:
ASCII, binary, and
MAT files.
要得到
MATLAB
< br>中可用来读写各种文件格式的完全函数列表,可以键入以下命令:
help iofun
MATLA
B
中有两种文件
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 file I/O
routines
并给出一些例子帮助理解概念。
转
LOAD/SAVE
主要的
high level file I/O
routines
是
LOAD
和
p>
SAVE
函数。
LOAD
可以读
MAT-file
data
或者用空格间隔的格式相似的
ASCII data.
SAVE
可以将
MATLAB
变量写入
MAT-
file
格式或者空格间隔的
ASCII
data
。大多数情况下,语法相当简单。下面的例子用到数值由空格间隔的
ASCII filesample_
:
1 5 4 16 8
5 43 2 6 8
6 8 4
32 1
90 7 8 7 6
5 9 81 2 3
Example:
用
LOAD and SAVE
读写数据
[Copy to clipboard][-]CODE:
% Load the file to the matrix, M :
M = load('sample_')
% Add 5 to M :
M = M +5
% Save M to a .mat file
called 'sample_file_':
save
sample_file_plus5 M
% Save
M to an ASCII .txt file called 'sample_file_' :
save sample_file_ M -ascii
UIGETFILE/UIPUTFILE
UIGETFILE/UIPUTFILE
< br>是基于图形用户界面(
GUI
)的。会弹出对话框,列出
当前目录的文件和目录,
提示你选择一个文件。
UIGETFI
LE
让你选择一个文件来写(类似
Windows
?
另存为
?
选项?)
p>
。用
UIGETFILE
,可以选择已存在
的文件改写,也可以输入新的文件名。两个函数的返回值是所选文件名和
路径。
Example:
用
UIGETFILE
从当前目录选择一个
M-file
[Copy to clipboard][-]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 file
s
。
文件也必须是
homogeneo
us
。
I
MPORTDATA
形成
UIIMPORT
的功能,不打开
GUI
。可以将
I
MPORTDATA
用于函数或者脚本中,因为
在函数或者脚本
中基于
GUI
的文件导入机制并不理想。下面的例子用到包含几
行文件头和文本、数值
数据的文件
'sample_'
:
This is
a file header
.
This is file is an example.
col1 col2 col3 col4
A 1 4 612.000
B
1 4 613.000
C 1 4 614.000
D 1 4 615.000
Example: Using IMPORTDATA to read in a
file with headers, text, and numeric data
[Copy to clipboard][-]CODE:
% This reads in the file 'sample_' and
creates a
% structure D that contains
both data and text data.
% Note the
IMPORTDATA command specifies a white space
% as the delimiter of the file, but
IMPORTDATA can usually
% detect this on
its own
D =
importdata('sample_','')
%
原文有误?
D = importdata('sample_') <
/p>
可以通过访问结构
D
的数据和文本域,来
看结构
D
中的真实值,例如输入:
data =
text = ta
可以用
UIIMPORT
读同一个文件并得到同样的结构
.
注意
:
对于
ASCII data,
你必须检验导入向导正确的识别了列分隔符。
TEXTREAD/STRREAD
TEXTREAD
是一个强大的动态
high level routine
,设计用来读
ASCII
格式的文本和
/
或数值数据文件。
STRREAD
除是从字符串而不是文件读以外,类似于
TEXTREAD
。
两个函数可以用许多参数来改变其
具体的工作方式,
他们返回读入指定输出的数据。
他们有效的提
供给
你一个
“
两全其美
”
的方法,因为他们可以用一个命令读入混合的
p>
ASCII
和数值数据(
high
level
routines
的做<
/p>
法)
,并且你可以改变他们以匹配你特定的应用(如同
low level routines
做到的)
。例子:
[Copy to clipboard][-]CODE:
Example 1: Using TEXTREAD to read in an
entire file into a cell array
% This command reads in the file fft.m
into the cell array, file
file = textread('fft.m','%s','delimiter
','n','whitespace','');
[Copy to
clipboard][-]CODE:
Example 2: Using
STRREAD to read the words in a line
% This command uses the cell array
created in Example 1 to
% read in each
word of line 28 in 'file' to a cell array, words
words =
strread(file{28},'%s','delimiter','')
[Copy to clipboard][-]CODE:
Example 3: Using TEXTREAD to read in
text and numeric data from a file with
headers
% This
command skips the 2 header lines at the top of the
file
% and reads in each column to the
4 specified outputs
[c1 c2
c3 c4] = textread('sample_','%s %s %s
%s','headerlines',2)
[Copy to clipboard][-]CODE:
Example 4: Using TEXTREAD to read in
specific rows of text and numeric data from a
file
% This
command reads in rows B and C of the file. The
'headerlines'
% property is used to
move down to the desired starting row and the
% read operation is performed 2 times
[c1 c2 c3 c4] =
textread('sample_',...
'%s %s %s
%s',2,'headerlines',4)
[Copy to clipboard][-]CODE:
Example operator
[c2 c3 c4] = textread('sample_','%*s %d
%d %f','headerlines',3)
DLMREAD
< br>和
DLM
WRITE
函数能够读
写分隔的
ASCII
data
,
而不是用
low
level
routines
。
他们比
low
level
routines
容易使用,
Low
level routines
用几行代码实现的功能可以用<
/p>
DLMREAD/DLMWRITE
简化成一
行。
CSVREAD
用来读分隔符是逗号的文件,是
DLMREAD
的特殊情况。当读空格和
T
ab
分隔的
电子数据表
文件时,
DLMREAD
特
别有用。以
'sample_'
为例:
[Copy to clipboard][-]CODE:
Example 1: Using DLMREAD to read in a
file with headers, text, and numeric
data
% This
reads in the file 'sample_' and creates a matrix,
D,
% with the numeric data
this command specifies a white space as
the
% delimiter of the
file
D =
dlmread('sample_','')
[Copy to
clipboard][-]CODE:
Example
2: Using DLMREAD to extract the first 3 columns of
the last 3 rows
% This reads in the first 3 columns of
the last 3 rows of
% the
data file 'sample_'into the matrix,
D_partial.
%
读文件
'sample_'
前
3
列后
3
行,到矩阵
D_partial.
D_partial =
dlmread('sample_','',[2 0 4 2])
[Copy to clipboard][-]CODE:
Example 3: Using DLMWRITE to write a
comma delimited file
% This creates a file called '' that
consists of
% the first 3
columns of the last 3 rows of data where
each
% element is separated
by a comma
dlmwrite('',D_partial,',')
注意
:
保证
DLMREAD and DLMWRITE
指定范围的指标从
0
开始,而不是从
1
开始。
WK1READ/WK1WRITE
WK1READ
用来读
Lotus123
电子数据表文件的数据;
WK1
WRITE
用来写矩阵到
Lotus123
电子数据表
文件。
XLSREAD
XLSREAD
< br>用来读
Excel
的数值和文本数据。
< br>
-----------------------
--------------------------------------------------
-------------------------------------------------<
/p>
-------------------------
三
.
具体例子分析:
Matlab
网站用两个例子非常详尽地介绍了各个命令的基本用法,实际中,面对手头上的数据,如何选<
/p>
用合适的命令呢?以下结合几个示例给出一些总结,大家举一反三就可以了:
1.
纯数据(列数相同)
:
源文件:
[Copy to clipboard][-]CODE:0 3866.162
2198.938 141.140
1 3741.139
2208.475 141.252
2 3866.200
2198.936 141.156
3 3678.048
2199.191 141.230
4 3685.453
2213.726 141.261
5 3728.769
2212.433 141.277
6 3738.785
2214.381 141.256
7 3728.759
2214.261 141.228
8 3748.886
2214.299 141.243
9 3748.935
2212.417 141.253
10 3733.612
2226.653 141.236
11 3733.583
2229.248 141.223
12 3729.229
2229.118 141.186
解答
:对于这个
txt
文件,由于各行列数相同,故简单地使用
load,
importdata
均可。
2.
字段名(中、英文字段均可)<
/p>
+
数据:
源文件:
[Copy to clipboard][-]CODE:CH0 CH1 CH2
CH3
0.000123 0.000325
0.000378 0.000598
0.000986
0.000256 0.000245 0.000698
解
答
:由于是记录的形式,因此各行列数必相同(缺少部分列时请自行在文件中补上
Inf
或
p>
NaN
)
,
故直接
使用
importdata
便可。
3
.
注释(含有独立的数字串)
+
数据(
列数相同)
:
问题
< br>:
这个文件有
4
列
,
但前
6
行是文字说明
p>
,4
列数字是从第
8
行开始的
.
现在我想把这个文件的前
2
列
和文字说明提出来组成一个新的
d
at
文件
源文件:
[Copy to clipboard][-]CODE:Group 2
12.02.2006
Limei
Samples CH1
CH2
CH3
0.000123
0.000325 0.000378 0.000598
0.000986
0.000256 0.000245 0.000698
目标文件:
[Copy to
clipboard][-]CODE:Group 2 12.02.2006
Limei
Samples of datas:
50000
CH0
CH1