MATLAB处理小数据没问题,一碰到文件读写就抓瞎?fopen打开了忘关、fscanf格式写错、fseek指针乱跳——这些坑我全踩过。2026年R2026a版本的文件操作函数跟老版本差别不大,但帮助文档更新了不少。下面把打开、读写、定位这3块共12个函数全拆开,每个配实际代码,照着抄就能跑。
很多人写MATLAB程序,变量全存在工作区里,跑完就关了,从来不碰文件。但工作区内存是有限的,处理超过2GB的数据就得跟磁盘文件打交道。
MATLAB的文件操作函数基于ANSI标准C语言库实现,所以如果你学过C,会发现fopen、fclose、fscanf这些函数眼熟得很。不熟悉也没关系,下面逐个讲。
所有文件操作的第一步都一样:打开文件,拿到文件识别号fid,操作完关闭文件释放缓冲区。这步跳过,后面全白搭。
fopen的调用格式:
matlabfid = fopen(filename, permission)
fid是文件识别号,打开成功返回一个正整数,失败返回-1。permission决定你能对文件干什么。
| permission | 含义 | 你不知道的细节 |
|---|---|---|
r | 只读,文件不存在直接报错 | 默认方式,最常用 |
w | 写入,文件不存在就创建,存在就清空 | 危险操作,别手滑 |
a | 追加,数据写到文件末尾 | 写日志用这个 |
r+ | 读写,文件必须已存在 | 改配置文件用 |
2026年版本里还有个容易忽略的点:fopen默认打开的是二进制文件。如果你操作的是.txt文本文件,permission后面必须加t,写成rt、wt、at。我见过不少人打开文本文件忘加t,读出来全是乱码,排查半天。
matlabfid = fopen('old.txt', 'rt'); % 文本文件只读
fid = fopen('new.dat', 'r+'); % 二进制文件读写
关文件用fclose:
matlabstatus = fclose(fid); % 关单个文件,成功返回0
status = fclose('all'); % 关所有已打开的文件
不关文件会怎样?缓冲区占着不释放,下次打开同一个文件会报"权限被占用"。我之前跑一个循环处理500个文件,每次忘关fclose,跑到第387个就崩了。后来加了一句fclose(fid),稳了。
fscanf从文本文件按指定格式读数据进矩阵:
matlab[A, count] = fscanf(fid, fmt, size)
fmt是格式控制符,几个常用的:
| 格式符 | 读什么 | 例子 |
|---|---|---|
%d | 十进制整数 | 读出来是123 |
%f | 小数实数 | 读出来是3.14 |
%s | 不含空格的字符串 | 读出来是hello |
%c | 单个字符 | 读出来是A |
%x | 十六进制整数 | 读出来是0xff |
%6.2f这种写法什么意思?总宽度6位,小数占2位,不够前面补空格。
matlabx = fscanf(fid, '%5d', 100); % 读100个整数进向量
y = fscanf(fid, '%5d', [10, 10]); % 读100个整数进10×10矩阵
fprintf反过来,把数据按格式写入文本文件:
matlabcount = fprintf(fid, fmt, A)
看个实际例子。算x从0到1、步长0.1的指数函数值,写入demo1.txt:
matlabx = 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)占12位小数8位。生成的文件长这样:
0.00 1.00000000
0.10 1.10517092
0.20 1.22140276
...
1.00 2.71828183
用type demo1.txt就能在命令窗口看到内容。
fscanf一次读一整块,fgetl和fgets是按行读,更适合处理有换行的文本文件。
matlabline = fgetl(fid); % 读一行,不含换行符,到末尾返回-1
line = fgets(fid, nchar); % 读一行,保留换行符,最多读nchar个字符
逐行读demo1.txt的代码:
matlabfid = fopen('demo1.txt', 'r');
while 1
line = fgetl(fid);
if line < 0
break
end
disp(line);
end
fclose(fid);
这段代码的逻辑很清楚:一行一行读,读到-1就停。比fscanf写起来简单,而且不用管格式符。
load函数只能读固定格式的ASCII文件,数据之间必须用空格对齐。但实际工作中的数据文件,列之间是逗号、分号、制表符隔开的,load直接罢工。
这时候用textscan:
matlabC = textscan(fid, fmt, N, param, value)
param参数能跳过标题行。比如textdemo.txt里有标题行,后面4行是学生成绩:
Name Chinese English Math
wang 99 98 100
Li 98 89 0
Zhang 80 90 97
Zhao 77 65 87
跳过第一行标题,读前3个学生的数据:
matlabfid = fopen('textdemo.txt', 'r');
grades = textscan(fid, '%s %d %d %d', 3, 'headerlines', 1);
fclose(fid);
grades是个单元数组,grades{1}是姓名,grades{2}是语文成绩,以此类推。2026年R2026a版本的textscan支持直接指定分隔符为逗号,写成'Delimiter', ','就行,读CSV文件不用自己拆字符串了。
处理图像、音频、二进制数据,必须用fread和fwrite。
matlab[A, count] = fread(fid, size, precision, skip)
count = fwrite(fid, A, precision)
precision指定数据类型,几个常用的:
| 标识符 | 类型 | 字节数 |
|---|---|---|
int8 | 8位有符号整数 | 1 |
int32 | 32位有符号整数 | 4 |
float32 | 32位浮点 | 4 |
double | 64位双精度 | 8 |
存一个5阶魔方阵到magic5.dat:
matlabfid = fopen('magic5.dat', 'w');
cnt = fwrite(fid, magic(5), 'int32');
fclose(fid);
读回来:
matlabfid = fopen('magic5.dat', 'r');
[B, cnt] = fread(fid, [5, inf], 'int32');
fclose(fid);
B就是原来的魔方阵,cnt是读出的元素个数25。
fread还有个skip参数,能周期性跳过数据。比如每隔3个数据读1个,skip设为3。这个功能在读传感器原始数据时特别有用,原始数据里夹杂着时间戳,用skip直接跳过就行。
打开文件后,MATLAB会维护一个文件位置指针,指向当前读写位置。fseek用来移动指针,ftell用来查指针在哪。
matlabstatus = fseek(fid, offset, origin)
position = ftell(fid)
origin有3个取值:'bof'或-1(文件头)、'cof'或0(当前位置)、'eof'或1(文件尾)。
matlabfseek(fid, 0, -1); % 指针回到文件开头
fseek(fid, -5, 'eof'); % 指针移到文件尾前第5个字节
看个实际例子:
matlaba = 1:5;
fid = fopen('fdat.bin', 'w');
fwrite(fid, a, 'int16');
fclose(fid);
fid = fopen('fdat.bin', 'r');
fseek(fid, 6, 'bof'); % 指针移到第4个元素(6字节处)
four = fread(fid, 1, 'int16'); % 读出4
position = ftell(fid); % 指针在8字节处
fseek(fid, -4, 'cof'); % 指针往回退4字节
three = fread(fid, 1, 'int16'); % 读出3
fclose(fid);
运行结果:four=4,position=8,three=3。指针移动逻辑很清晰,往前走6字节读到第4个数,ftell告诉你现在在第8字节,往回退4字节就读到第3个数。
feof判断指针是否到了文件尾:
matlabstatus = feof(fid) % 到末尾返回1,没到返回0
ferror查最近一次I/O操作有没有出错:
matlabmessage = ferror(fid) % 出错返回错误信息,没出错返回空
这两个函数平时用得少,但调试的时候能救命。比如你读文件读到一半程序崩了,用feof一查,发现指针没到末尾,说明不是文件读完了,是中间某个数据格式不对导致fread失败。再用ferror一查,错误信息直接告诉你哪里出了问题。

写文件操作的代码,我的习惯是每次fopen之后立刻判断fid是不是-1,每次fclose之后用ferror确认有没有写入错误。多写两行代码,能省掉几小时的调试时间。2026年了,MATLAB的文件操作函数没什么大变化,但这些细节决定了你的代码是能跑还是能稳定地跑。
武汉格发信息技术有限公司,格发许可优化管理系统可以帮你评估贵公司软件许可的真实需求,再低成本合规性管理软件许可,帮助贵司提高软件投资回报率,为软件采购、使用提供科学决策依据。支持的软件有: CAD,CAE,PDM,PLM,Catia,Ugnx, AutoCAD, Pro/E, Solidworks 等。