欧亿体育
工作动态
我的位置: 首页 > 工作动态
MATLAB 之 文件操作
发布时间:2024-01-08 16:01
  |  
阅读量:
  |  
作者:
欧亿体育

这里写目录标题

  • MATLAB 语言和其他程序设计语言一样,程序运行中的所有变量都保存在称为工作区的内存空中,这些变量可以在程序中直接引用。
  • 但是工作区的大小是有限的,如果处理的数据较大,就需要和磁盘文件中的数据进行交换。
  • 有时要从外部设备中输入数据,有时要把程序处理过的数据输出到外部设备中。
  • MATLAB 提供了多种不同层次的数据输入/输出函数。MATLAB 提供多种方法支持将磁盘文件和剪贴板中的数据导入到 MATLAB 的工作区。
  • 最简单的办法是使用数据导入向导(可通过在 “主页” 选项卡 “变量” 命令组中单击“导入数据”命令按钮或在命令行窗口执行 uiimport 命令来激活它),而在程序中则可以使用 MATLAB 文件操作函数。

一、文件操作

  • MATLAB 提供了一系列文件操作函数,这些函数是基于 ANSI 标准 C 语言库实现的,所以两者的格式和用法有许多相似之处。
  • 其中,ANSI 标准是美国国家标准学会(AMERICAN NATIONAL STANDARDS INSTITUTE: ANSI)成立于 1918 年。当时,美国的许多企业和专业技术团体,已开始了标准化工作,但因彼此间没有协调,存在不少矛盾和问题。为了进一步提高效率,数百个科技学会、协会组织和团体,均认为有必要成立一个专门的标准化机构,并制订统一的通用标准。

1. 文件打开与关闭

  • 对一个文件进行操作以前,必须先打开该文件,系统将为其分配一个输入/输出缓冲区。当文件操作结束后,还应关闭文件,及时释放缓冲区。

1.1 fopen 函数

  • fopen 函数用于打开文件以供读写,其调用格式如下:
fid=fopen(filename, permission)
  • 其中,fid 为文件识别号,filename 为待操作的文件,permission 为对文件的允许使用方式。
  • 打开文件成功时,fid 返回一整数,用来标识该文件;打开文件不成功时,fid=-1。
  • permission 常用值如下表所示。
参数 允许使用方式
r 以读方式打开一个文件。如果指定的文件不存在,则返回值为 -1。这是默认方式。
w 以写方式打开一个文件。如果指定的文件不存在,则创建一个新文件,再打开它;如果存在,则打开该文件,并清空原有内容。
a 打开一个文件,随后的操作可在该文件末尾添加数据。
r+ 以读和写方式打开一个文件。
  • fopen 函数默认打开二进制文件,如果打开的是文本文件,则需要在上述允许方式后加 t,加 rt、wt 等。例如:
F1=fopen('old.txt','rt')	%打开一个名为old.txt的文本文件,允许进行读操作
F2=fopen('new.dat','r+')	%打开一个名为new.dat的二进制文件,允许进行读和写操作

1.2 fclose 函数

  • fclose 函数用于关闭已打开的文件,其调用格式如下:
status=fclose(fid)
  • 关闭标识为 fid 的文件。
  • 如果 fid 为 all,则关闭所有已打开的文件,但标准文件除外。返回 0 表示关闭成功,返回 -1 则表示关闭不成功。

2. 文件的读写

2.1 fscanf 函数

  • fscanf 函数用于读取文本文件的内容,并按指定格式存入矩阵,其调用格式如下:
[A,count]=fscanf(fid,fmt,size)
  • 其中,A 用于存放读取的数据,count 返回成功读取的数据元素个数,fid 为文件识别号,fmt 用以控制读取的数据格式,size 指定读取多少数据。
  • 数据格式由%加上格式符组成,常见的格式符如下表所示。
格式符 含义
%d 十进制整数
%f 小数形式的实数
%u 无符号的十进制整数
%g 根据输出项的大小自动选择 e 格式或 f 格式
%o 八进制整数
%c 字符
%x 十六进制整数(0~9,a~f)
%s 不包含空格的字符串
%e 指数形式的实数
  • 在 % 之后还可以加上数据宽度。例如,%3d,它控制读取的整型数据取 3 位数字;%10.3f 控制读取实型数据,取 10 个字符(含小数点),小数部分占 3 位。
  • size 可以取下列值。
  • (1) N:表示读取 N 个元素到一个列向量。
  • (2) inf:表示读取整个文件。
  • (3) [m,n]:表示读数据到 m × n m×n m×n 的矩阵中,数据按列存放。
  • 例如:
x=fscanf(fid,'%5d',100);		%从指定文件中读取100个整数,并存入向量x中
y=fscanf(fid,'%5d',[10,10]);	%将读取的100个整数存入10×10矩阵y中

2.2 fprintf 函数

  • fprintf 函数可以将数据按指定格式写入到文本文件中,其调用格式如下:
count=fprintf(fid,fmt,A)
  • 其中,fid 和 fmt 的意义与 fscanf 函数相同,A 存放要写入文件的数据,count 返回成功输出的字节数。
  • 先按 fmt 指定的格式将数据矩阵 A 格式化,然后写入到 fid 所关联的文件。如果不指定 fid,则默认输出到屏幕。
  • 例如,我们计算当 x = [ 0.0 , 0.1 , 0.2 , … , 1.0 ] x=[0.0,0.1,0.2,…,1.0] x=[0.00.10.21.0] 时, f ( x ) = e x f(x)=e^{x} f(x)=ex的值,并将结果写入文件 demo1.txt。
  • 程序如下:
x=0:0.1:1;
Y=[x;exp(x)];
fid=fopen('demo1.txt','w');
fprintf(fid,'%6.2f%12.8f\n',Y);
fclose(fid);
  • 程序中 %6.2f 控制 x 的值占 6 位,其中小数部分占 2 位。同样,%12.8f 控制指数函数 exp(x) 的输出格式。由于是文本文件,可以在 MATLAB 命令行窗口用 type 命令显示其内容。
>> type demo1.txt
  • 显示的文件内容如下所示。
  0.00  1.00000000
  0.10  1.10517092
  0.20  1.22140276
  0.30  1.34985881
  0.40  1.49182470
  0.50  1.64872127
  0.60  1.82211880
  0.70  2.01375271
  0.80  2.22554093
  0.90  2.45960311
  1.00  2.71828183

2.3 fgetl 与 fgets函数

  • 除上述对文本文件进行读写操作的函数外,读取文本文件的函数还有 fgetlfgets,它们按行读取数据,其调用格式如下:
line=fgetl (fid)
line=fgets(fid,nchar)
  • fgetl 命令读入的字符串中不包括换行符,如读到文件末尾,则返回 -1。该命令只能对文本格式文件进行操作,如果读取没有换行符的二进制文件,则会运行很长时间。
  • fgets 命令读入数据时保留原文件中的换行符,输入可选项 nchar 是整型数,如果指定此项数值,则读入一行时最多读 nchar 个字符。
  • 例如,我们上例中生成的文件 demo1.txt 中的数据。
  • 程序如下:
fid=fopen('demo1.txt','r');
while 1
	line=fgetl(fid);
	if line<0
		break
	end
	disp(line);
end
fclose(fid);
  • 该程序把文件 demo1.txt 一行一行地读入到 line 中,每度一行在屏幕上显示一次,直至文件末尾。当读到文件末尾时,line 的返回值为 -1,终止读操作。

2.4 textscan 函数

  • load 函数和 save 函数是 MATLAB 中为装载和存储数据提供的工具,但 load 函数只能读取以 ASCII 形式存储、每一行数据为固定长度的文件。
  • 如果一个文件中的数据全部由 ASCII 字符组成,且数据间有间隔符(如空格、逗号、分号、制表位),则文件称为有格式文件。
  • 有格式文件可以使用文本输入函数 textscan 读取数据,函数调用格式如下:
C=textscan(fid,fmt,N,param,value)
  • 其中,C 为单元矩阵,fid 为待操作的文件识别号,fmt 用以控制读取的数据格式,N 指定重复使用该格式的次数,param 指定一些特殊操作,value 是与特殊操作有关的值。例如,跳过两行标题行可将 ‘headerlines’ 参数设为 2。
  • 例如,我们假定文件 textdemo.txt中有以下格式的数据:
Name Chinese English Mathmatics
wang 99 98 100
Li 98 89 0
Zhang 80 90 97
Zhao 77 65 87
  • 此文件第一行为标题行,第 2~5 行的第 1 列为字符型,后 3 列为整型。从该文件中将前 3 个数据读入到 grades 的程序段如下:
fid=fopen('textdemo.txt','r');
grades=textscan(fid,'%s %d %d %d',3,'headerlines',1);

2.5 fread 函数

  • 该函数从文件中读入二进制数据,其调用格式如下:
[A,count]=fread(fid,size,precision,skip)
  • 其中,A 用于存放读取的数据,count 返回所读取的数据元素个数,fid 为文件识别号,size 用于指定读入数据的元素数量(可取值与 fscanf 函数相同,省略时则读取整个文件内容),precision 指定读写数据的类型,常用的数据类型详细如下表所示,其默认值为 uchar。
标识符 说明
schar 有符号字符
uchar 无符号字符
int8、int16、int32、int64 8~64 位有符号整数
uint8、uint16、int32、uint64 8~64 位无符号整数
float32 32 位浮点数
float64、double 64 位双精度型数
  • skip 称为循环因子,若指定 skip 值且该值不为 1,则按 skip 指定的比例周期性地跳过一些数据,使得读取的数据具有选择性。
  • 例如,我们按 32 位有符号数据格式读取文件 exmp1.dat 的前 100 个数据,并将其放入向量 d d d
  • 程序如下:
fid=fopen('exmp1.dat','r');
d=fread(fid,100,'int32');
  • 例如,我们假设文件 alphabet.txt 的内容是按顺序排列的 26 个大写英文字母,读取前 5 个字母的 ASCII 和这 5 个字符。
  • 程序如下:
fid=fopen('alphabet.txt','r');
c=fread(fid,5);
frewind(fid);
d=fread(fid,5,'*char');
fclose(fid);
  • 其中,frewind 函数用于将文件位置指针返回到文件的起始位置。
  • fscanffread 函数在读取数据时较灵活,不论数据文件中的数据是否具有确定的规律,均可以将数据文件的全部数据读入。
  • load 函数在载入数据时,要求数据文件中的数据是有规律排列的,数据的排列类似矩阵或表格形式,否则不能成功读取数据。

2.6 fwrite 函数

  • fwrite 函数按照指定的数据类型将矩阵中的元素写入到文件中,其调用格式如下:
count=fwrite(fid,A,precision)
  • 其中,count 返回成功写入文件的数据元素个数,fid 为文件句柄,A 用来存放要写入文件的数据,precision 用于控制所写数据的类型。
  • 例如:
fid=fopen('aaa.dat','w') ;
fwrite(fid,x,'float32');
  • 将矩阵 X 中的数据用 32 位浮点格式写入 aaa.dat 文件。
  • 例如,我们建立一数据文件 magic5.dat,用于存放 5 阶魔方阵。
  • 程序如下:
fid=fopen('magic5.dat','w');
cnt=fwrite(fid,magic(5),'int32');
fclose(fid);
  • 上述程序段将 5 阶魔方阵以 32 位整数格式写入文件 magic5.dat 中。
  • 下列程序则可实现对数据文件 magic5.dat 的读操作。
fid-fopen('magic5.dat','r');
[B,cnt]=fread(fid,[5,inf],'int32')
fclose(fid);
  • 程序运行结果如下:
B =

    17    24     1     8    15
    23     5     7    14    16
     4     6    13    20    22
    10    12    19    21     3
    11    18    25     2     9


cnt =

    25
    

3. 数据文件定位

  • 当打开文件并进行数据的读写时,需要判断和控制文件的读写位置,例如,判断文件数据是否已读完,或者需要读写指定位置上的数据等。
  • MATLAB 自动创建一个文件位置指针来管理和维护文件读写数据的起始位置。

3.1 fseek 函数

  • 该函数用于定位文件位置指针,其调用格式如下:
status=fseek(fid,offset,origin)
  • 其中,fid 为文件识别号;offset 表示位置指针相对移动的字节数,若为正整数表示向文件尾方向移动,若为负整数表示向文件头方向移动。
  • origin 表示位置指针移动的参照位置,它的取值有 3 种可能:‘cof’ 或 0 表示文件的当前位置,‘bof’ 或 -1 表示文件的开始位置,'eof’ 或 1 表示文件的结束位置。
  • 若定位成功,status 返回值为 0,否则返回值为 -1。
  • 例如:
fseek(fid,0,-1)			%指针指向文件头
fseek(fid,-5,'eof')		%指针指向文件尾前第5个字节

3.2 ftell 函数

  • 该函数用来查询文件指针的当前位置,其调用格式如下:
position=ftell(fid)
  • ftell 函数的返回值为从文件头到指针当前位置的字节数。若返回值为 -1,表示获取文件当前位置失败。
  • 例如,我们编写如下程序,当程序运行后,变量 four、position 和 three 的值是多少?
  • 所编写程序如下:
a=1:5;
fid=fopen('fdat.bin','w');		%以写方式打开文件
fdat.binfwrite(fid,a,'int16');	%将a的元素以双字节整型写入文件fdat.bin
fclose(fid);
fid=fopen('fdat.bin','r');		%以读数据方式打开文件fdat.bin
status=fseek(fid,6,'bof');	 	%将文件指针从开始位置向尾部移动6个字节
four=fread(fid,1,'int16');		%读取第4个数据,并移动指针到下一个数据
position=ftell(fid);			%ftell的返回值为8
status=fseek(fid,-4,'cof'); 	%将文件指针从当前位置往前移动4个字节
three=fread(fid,1,'int16');		%读取第3个数据
status=fclose(fid);
  • 程序运行后,four 的值是 4,position 的值是 8 和 three 的值是 3。

3.3 feof 函数

  • 该函数用来判断当前的文件位置指针是否到达文件尾部,其调用格式如下:
status=feof(fid)
  • 当到达文件结束位置时,测试结果为 1,否则返回 0。

3.4 ferror 函数

  • 该函数用来查询最近一次输入或输出操作中的出错信息,其调用格式如下:
message-ferror(fid)