第11章 输入与输出
第11章 输入与输出
11.1 文件的打开与关闭
11.1.1 打开文件
fid=fopen(fname,permission) % 打开文件fname,并返回大于或等于3的整数文件标识符
[fid,msg]=fopen(fname,permission)
fids=fopen('all') % 返回包含所有打开文件的文件标识符的行向量
fname=fopen(fid) % 返回上一次调用fopen打开fid指定的文件时所使用的文件名
| 字符串 | 含义 |
|---|---|
| 'r' | 只读文件(reading) |
| 'w' | 只写文件,覆盖文件的原有内容(如果文件名不存在,则生成新文件,writing) |
| 'a' | 增补文件,在文件尾部增加数据(如果文件名不存在,则生成新文件,appending) |
| 'r+' | 读/写文件(不生成文件,reading and writing) |
| 'w+' | 创建一个新文件或删除已有文件内容,并可进行读/写操作 |
| 'a+' | 读取和增补文件(如果文件名不存在,则生成新文件) |
| 'A' | 打开文件以追加(但不自动刷新)当前输出缓冲区 |
| 'W' | 打开文件以写入(但不自动刷新)当前输出缓冲区 |
fid=fopen('exam.dat','r') % 以只读方式打开二进制文件exam.dat
fid=fopen('junk','r+') % 打开文件junk,并对其进行二进制形式的输入和输出操作
fid=fopen('junk','w+') % 创建新文件junk,对其进行二进制形式的输入和输出操作;如果该文件已存在,则旧文件内容将被删除
fid=fopen('outdat','wr') % 创建并打开输出文件outdat,等待写入数据
fid=fopen('outdat','at') % 打开要增加数据的输出文件outdat,等待写入数据
11.1.2 关闭文件
fclose(fid) % 关闭文件标识为fid的文件
fclose('all') % 关闭所有文件
status=fclose(___) % 返回操作结果,文件关闭成功后,status将为0,否则为-1
11.2 文件的读写
11.2.1 读取二进制文件
A=fread(fid) % 将打开文件中的数据读取到列向量A中,并将文件指针定位在文件结尾标记处
A=fread(fid,sizeA) % 将文件数据读取到维度为sizeA的数组A中(按列顺序填充A)
A=fread(fid,precision) % 根据precision描述的格式和大小解释文件中的值
A=fread(fid,sizeA,precision)
A=fread(___,skip) % 在读取文件中的每个值之后将跳过skip指定的字节或位数
A=fread(___,machinefmt) % 另外指定在文件中读取字节或位时的顺序
[A,count]=fread(___) % 将返回fread读取到A中的字符数
其中,fid是用fopen打开的一个文件的文件标识;A是包含有数据的数组;count用来读取文件中变量的数目;sizeA是要读取文件中变量的数目,它有以下3种形式。
- inf:读取文件中的所有值。执行完后,array将是一个列向量,包含有从文件中读的所有值。
- [n,m]:从文件中精确定地读取n*m个值,array是一个n*m 的数组。如果fread行到达文件结尾,而输入流没有足够的位数来写满指定精度的数组元素,fread就用最后一位的数值或0填充,直到得到全部的值。
- n:准确地读取n个值。执行完后,array将是一个包含有n个值的列向是
如果发生错误,那么读取将直接到达最后一位。参数precision主要包括两部分:一是数据类型定义,如 int、float 等;二是一次读取的位数。默认情况下,precision是uchar(8位字符型)。
| 字符串 | 描述 | 字符串 | 描述 |
|---|---|---|---|
| 'uchar' | 无符号字符型 | 'int8' | 整型(8位) |
| 'schar' | 带符号字符型(8位) | 'int16' | 整型(16位) |
| 'single' | 浮点数(32位) | 'int32' | 整型(32位) |
| 'float32' | 浮点数(32位) | 'int64' | 整型(64位) |
| 'double' | 浮点数(64位) | 'uint8' | 无符号整型(8位) |
| 'float64' | 浮点数(64位) | 'uint16' | 无符号整型(16位) |
| 'bitN' | N位带符号整数(1≤N≤64) | 'uint32' | 无符号整型(32位) |
| 'ubitN' | N位无符号整数(1≤N≤64) | 'uint64' | 无符号整型(64位) |
新建“脚本 dingzx.m 文件”
a=1:.2:3*pi;
b=sin(2*a);
plot(a,b+1);
>> dingzx
>> fid=fopen('dingzx.m','r');
>> data=fread(fid);
>> disp(char(data'));
a=1:.2:3*pi;
b=sin(2*a);
plot(a,b+1);
>> fid=fopen('nine.bin','w');
>> fwrite(fid,[1:6]); % 将一个六元素向量写入示例文件
>> fclose(fid);
>> fid=fopen('nine.bin');
>> A=fread(fid) % 返回一个列向量,文件中的每一个字节对应一个元素
A =
1
2
3
4
5
6
>> whos A % 查看A的相关信息
Name Size Bytes Class Attributes
A 6x1 48 double
>> fclose(fid);
| 字符串 | 描述 | 字符串 | 描述 |
|---|---|---|---|
| 'char' | 字符型(8位,有符号或无符号) | 'ushort' | 无符号整型(16位) |
| 'short' | 整型(16位) | 'uint' | 无符号整型(32位) |
| 'int' | 整型(32位) | 'ulong' | 无符号整型(32位或64位) |
| 'long' | 整型(32位或64位) | 'float' | 浮点数(32位) |
11.2.2 写入二进制文件
fwrite(fid,A) % 将数组A的元素按列顺序以8位无符号整数的形式写入二进制文件
fwrite(fid,A,precision) % 按照precision说明的形式和大小写入A中的值
fwrite(fid,A,precision,skip) % 在写入每个值之前跳过skip指定的字节数或位数
fwrite(fid,A,precision,skip,machinefmt) % 额外指定将字节或位写入文件的顺序
count=fwrite(___) % 返回A中fwrite已成功写入文件的元素
其中,fid是用fopen打开的一个文件的文件标识;A是写入变量的数组;count是写入文件变量的数目;参数 precision 用于指定输出数据的格式;skip 用于指定在写入每个值之前跳过的字节数或位数;machinefmt指定字节或位写入文件的顺序。
>> fid=fopen('dingwrt.bin','w');
>> count=fwrite(fid,rand(4),'int32');
>> status=fclose(fid)
status =
0
>> fid=fopen('dingwrt.bin','r');
>> data=(fread(fid,16,'int32'))'
data =
1 1 0 1 1 0 0 1 1 1 0 1 1 0 1 0
11.2.3 写入文本文件
fprintf(fid,formatSpec,A1,...,An) % 按列顺序将字符串应用于数组A1,...,An的所有元素,并将数据写入一个文本文件
fprintf(formatSpec,A1,...,An) % 设置数据的格式并在屏幕上显示结果
count=fprintf(___) % 返回fprintf所写入的字节数
其中,fid由fopen产生,是要写入数据的那个文件的文件标识,如果fid丢失,则数据将写入标准输出设备(命令行窗口);formatSpec是控制数据显示的字符串;count是返回的成功写入的字节数;A1,...,An是MATLAB的数据变量。
fid值也可以是代表标准输出的1和代表标准出错的2,如果fid字段省略,则默认值为1,会被输出到屏幕上。常用的格式类型说明符如下。
- %e:科学计数形式,即将数值表示成a*10b的形式。
- %f:固定小数点位置的数据形式。
- %g:在上述两种格式中自动选取长度较短的格式。
可以用一些特殊格式,如 \n、\r、\t、\b、\f 等来产生换行、回车、tab、退格、走纸等字符。此外,还可以包括数据占用的最小宽度和数据精度的说明。
| 指定符 | 描述 | 指定符 | 描述 |
|---|---|---|---|
| %c | 单个字符 | %G | 与%g类似,只不过要用到大写的E |
| %d | 十进制表示(有符号) | %o | 八进制表示(无符号) |
| %e | 科学记数法(会用到小写的e,如3.1416e+00) | %s | 字符串 |
| %E | 科学记数法(会用到大写的E,如3.1416E+00) | %u | 十进制表示(无符号) |
| %f | 固定点显示 | %h | 用十六进制表示(用小写字母af表示) |
| %g | %e和%f中的复杂形式,多余的零将会被舍去 | %H | 用十六进制表示(用大写字母AF表示) |
| 标识(修改符) | 描述 |
|---|---|
| -(负号) | 数据在域中左对齐,如果没有这个符号,则默认为右对齐 |
| + | 输出时数据带有正负号 |
| 0 | 如果数据的位数不够,则用0填充前面的数 |
| 转义字符 | 描述 | 转义字符 | 描述 |
|---|---|---|---|
| \a | 警报 | \t | 水平制表 |
| \b | 退后一格 | \v | 垂直制表 |
| \f | 换页 | \ | 打印一个普通反斜杠 |
| \n | 换行 | ' ' | 打印一个单引号 |
| \r | 回车 | %% | 打印一个百分号(%) |
>> a=4:8;
>> b=[a; sqrt(a)];
>> fid=fopen('dingfp.dat','w');
>> fprintf(fid,'平方根表:\n'); % 输入标题文本
>> fprintf(fid,'%2.00f %5.5f\n',b); % 输出变量b的值
>> fclose(fid);
>> type dingfp.dat % 查看文件的内容
平方根表:
4 2.00000
5 2.23607
6 2.44949
7 2.64575
8 2.82843
11.2.4 读取文本文件
11.2.4.1 fscanf读取函数
A=fscanf(fid,formatSpec) % 将打开的文本文件中的数据读取到列向量A中
A=fscanf(fid,formatSpec,sizeA) % 将文件数据读取到维度为sizeA的数组A中
[A,count]=fscanf(___) % 额外返回读取到A中的字段数
其中,fid是所要读取文件的文件标识formatSpec是控制如何读取的格式字符串;A是接受数据的数组;输出参数count返回从文件中读取的变量的个数;参数sizeA指定从文件中读取数据的数目,它可以是一个整数n或[n,m],也可以是Inf。
- n:表示准确地读取n个值,执行完后,A将是一个包含有n个值的列向量;
- [n,m]:表示从文件中精确地读取n*m个值,A是一个n*m的数组;
- Inf:表示读取文件中的所有值,执行完后,A将是一个列向量,包含有从文件中读取的所有值。
formatSpec用于指定读入数据的类型,其常用的格式如下:
- %s:按字符串进行输入转换。
- %d:按十进制数据进行转换。
- %f:按浮点数进行转换。
>> x=100*rand(4,1);
>> fid=fopen('dingfc.txt','w');
>> fprintf(fid,'%4.4f\n',x); % 创建一个包含浮点数的示例文本文件
>> fclose(fid);
>> type dingfc.txt % 查看文件内容
42.1761
91.5736
79.2207
95.9492
>> fid=fopen('dingfc.txt','r'); % 打开要读取的文件并获取文件标识符
>> formatSpec='%f'; % 定义要读取的数据的格式,'%f'指定浮点数
>> A=fscanf(fid,formatSpec) % 读取文件数据并按列顺序填充输出数组A
A =
42.1761
91.5736
79.2207
95.9492
>> fclose(fid); % 关闭文件
11.2.4.2 fgetl和fgets读取函数
tline=fgetl(fid) % 从文件中把下一行(最后一行除外)当作字符串来读取,并删除换行符
tline=fgets(fid) % 从文件中把下一行(包括最后一行)当作字符串来读取,并包含换行符
tline=fgets(fid,nchar) % 返回下一行中的最多nchar个字符
% 以上两个函数的功能很相似,均可从文件中读取一行数据,区别在于fgetl会舍弃换行符,而fgets则保留换行符。
>> fid=fopen('badpoem.txt'); % 打开文件
>> line_ex=fgetl(fid) % 读取第一行,读取时排除换行符
line_ex =
'Oranges and lemons,'
>> frewind(fid); % 再次读取第一行,首先读取位置指针重置到文件的开头
>> line_in=fgets(fid) % 读取第一行,读取时包含换行符
line_in =
'Oranges and lemons,
'
% 通过检查fgetl和fgets函数返回的行的长度,比较两者的输出结果
>> length(line_ex)
ans =
19
>> length(line_in)
ans =
21
>> fclose(fid); % 关闭文件
11.2.5 文件格式化和二进制输入/输出比较
| 格式化文件 | 无格式化文件 |
|---|---|
| 能在输出设备上显示数据 | 不能在输出设备上显示数据 |
| 能在不同的计算机上很容易地进行移植 | 不能在不同的计算机上很容易地进行移植 |
| 相对地,需要较大的磁盘空间 | 相对地,需要较小的磁盘空间 |
| 慢:需要较长的计算时间 | 快:需要较短的计算时间 |
| 在进行格式化的过程中,会产生截断误差或四舍五入错误 | 不会产生截断误差或四舍五入错误 |
新建“脚本 compare.m 文件”
% 定义变量:count为读写计数器,fid为文件标识,in_array为输入数组,msg为弹出错误信息,out_array为输出数组,status表示运算,time以s为单位计时
out_array=randn(1,10000); % 产生10000个数据的随机数组
% (1)二进制输出操作计时
tic; % 重启秒表计时器
for ii=1:15 % 设置循环次数为15次
[fid,msg]=fopen('unformatted.dat','w'); % 打开二进制文件进行写入操作
count=fwrite(fid,out_array,'float64'); % 写入数据
ststus=fclose(fid); % 关闭文件
end
time=toc/15; % 获取平均运行时间
fprintf('未格式化文件的写入时间=%6.3f\n',time);
% (2)格式化输出操作计时
tic;
for ii=1:15
[fid,msg]=fopen('formatted.dat','wt'); % 打开格式化文件进行写入操作
count=fprintf(fid,'%24.15e\n',out_array);
ststus=fclose(fid);
end
time=toc/15;
fprintf('格式化文件的写入时间=%6.4f\n',time);
% (3)二进制输入操作计时
tic;
for ii=1:15
[fid,msg]=fopen('unformatted.dat','r'); % 打开二进制文件进行读取操作
[in_array,count]=fread(fid,Inf,'float64');
ststus=fclose(fid);
end
time=toc/15;
fprintf('未格式化文件的读取时间=%6.4f\n',time);
% (4)格式化输入操作计时
tic;
for ii=1:15
[fid,msg]=fopen('formatted.dat','rt'); % 打开格式化文件进行读取操作
[in_array,count]=fscanf(fid,'%f',Inf);
ststus=fclose(fid);
end
time=toc/15;
fprintf('格式化文件的读取时间=%6.3f\n',time);
>> compare
未格式化文件的写入时间= 0.002
格式化文件的写入时间=0.0082
未格式化文件的读取时间=0.0003
格式化文件的读取时间= 0.013
11.3 文件位置控制和状态函数
11.3.1 exist函数
ident=exist('item'); % 若条目item存在,就根据其类型返回一个值
ident=exist('item','kind'); % 指定所要搜索的item的类型kind
| 值 | 意义 |
|---|---|
| 0 | 没有发现条目 |
| 1 | 条目为当前工作区的一个变量 |
| 2 | 条目为M文件或未知类型的文件 |
| 3 | 条目是一个MEX文件 |
| 4 | 条目是一个Simulink模型或库文件 |
| 5 | 条目是一个内建函数 |
| 6 | 条目是一个p代码文件 |
| 7 | 条目是一个目录 |
| 8 | 条目是类 |
新建“脚本 outp.m 文件”
% 目的:打开一个输出文件,检测文件是否存在
% 定义变量:fid为文件的标识;out_fname为输出文件名;yn表示反馈(Yes/No)
out_fname=input('输入输出文件名:','s'); % 得到输出文件
if exist(out_fname,'file') % 检查文件是否存在
disp('输出文件已存在'); % 文件存在
yn=input('保留现有文件?(y/n)','s');
if yn == 'n'
fid=fopen(out_fname,'wt');
else
fid=fopen(out_fname,'at');
end
else
fid=fopen(out_fname,'wt'); % 文件不存在
end
fprintf(fid,'%s\n',date); % 输出数据
fclose(fid);
>> outp
输入输出文件名:outp
输出文件已存在
保留现有文件?(y/n)y
>> type outp
07-Jul-2025
11.3.2 ferror函数
msg=ferror(fid) % 为指定文件的I/O操作返回错误消息
[msg,errnum]=ferror(fid) % 额外返回与错误消息关联的错误编号
[msg,errnum]=ferror(fid,'clear') % 清除指定文件的错误指示符
>> fid=fopen('badpoem.txt','r'); % 打开要读取的文件
>> status=fseek(fid,-5,'bof') % 读取位置设置为从文件开始处算起的-5个字节
status =
-1
>> error=ferror(fid) % 获取文件中最近出现的错误的详细信息
error =
'偏移量错误 - 文件开始之前。'
>> fclose(fid); % 关闭文件
11.3.3 feof函数
status=feof(fid) % 返回文件末尾指示符的状态
11.3.4 ftell函数
positation=ftell(fid) % 返回指定文件中位置指针的当前位置
11.3.5 frewind函数
frewind(fid) % 将文件位置指针设置到文件的开头
11.3.6 fseek函数
status=fseek(fid,offset,origin) % 设定指针位置相对于origin的offset字节数
其中,fid是文件标识;offset是偏移量,以字节为单位,它可以是正数(向文件末尾方向移动指针)、0(不移动指针)或负数(向文件起始方向移动指针);origin是基准点,可以是bof(文件起始位置)、cof(指针目前位置)、eof(文件末尾),也可以用-1、0或1来表示。如果返回值status为0,则表示操作成功;返回-1表示操作失败。
>> a=rand(1,6);
>> fid=fopen('dingrd.bin','w');
>> fwrite(fid,a,'short');
>> status=fclose(fid);
>> fid=fopen('dingrd.bin','r');
>> rd=fread(fid,'short');
>> rd'
ans =
0 1 0 0 1 0
>> eof=feof(fid) % 测试指针是否在文件结束位置
eof =
1
>> frewind(fid);
>> status=fseek(fid,2,0) % 设置指针位置
status =
0
>> position=ftell(fid) % 返回fid对应的文件指针读/写的位置
position =
2

浙公网安备 33010602011771号