第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);

11.2.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
posted @ 2026-01-12 10:50  Zhuye_inking  阅读(17)  评论(0)    收藏  举报