Matlab学习:文本(以.txt为例)
文件、二进制文件数据、图像(以BMP、TIF、GIF、JPEG等图像为例)
文件、其他文件(以RAW、.dat为例)
的读取
1、读取 .txt 文件数据
情况A. 一个txt文件里全是数字数据
的读取
例如sj.txt
文件内容为:
1 21 31 41
2 52 62 74
3 33 35 37
4 81 82 83
5 55 66 77
方法1.maltab自带工具
首先先将数据导入至matlab自带的工具中
导入后会出现导入后的各个参数,
分隔符根据实际情况进行选择,一般是空格或者逗号,
最后点击导入所选内容即可。
方法2. load、dlmread、importdata函数
代码示例:
%%文件路径
Path='路径\'
filename=[Path ,'data.txt'];
%%读取文件数据
data1=load(filename);
data2=dlmread(filename);
data3=importdata(filename);
情况B.在情况A的基础上存在第一行数据为中文
例如sj2.txt
文件内容为:
编号 长 宽 高
1 21 31 41
2 52 62 74
3 33 35 37
4 81 82 83
5 55 66 77
分析内容:这里的文件内容,存在了一行中文汉字,load函数将不再适用,这里我们需要分为两个部分处理:1、中文处理;2、数字处理。
参考函数:textread
importdata
方法1.textread函数
data=textread('sj2.txt','%s'); %读取文件
data=str2num(char(data(5:end))); %删除中文,并将cell转换成数字
data=reshape(data,4,length(data)/4)'; %重新按照格式排列
方法2.importdata函数
data=importdata('sj2.txt'); %读取的文字存在struct内,data为数字,textdata为中文
data=data.data; %提取struct中的data
情况C.读取中文与数字混合文件
例如sj2.txt
文件内容为:
编号:1 长:21 宽:31 高:41
编号:2 长:52 宽:62 高:74
编号:3 长:33 宽:35 高:37
编号:4 长:81 宽:82 高:83
编号:5 长:55 宽:66 高:77
分析内容:这种固定的汉字和变化的数字,以形成汉字和数字混合出现,已经不能简单应用MATLAB自带函数处理,需要根据实际情况进行更加精准的处理。这里使用文件系统函数(fopen等函数
)读取文件。
关键函数:
fopen
打开文件,返回地址,因为我们只是读取文件,所以用r权限
fscanf
以某种方式读取文件,具体内容具体分析
fscanf(FID,FORMAT,SIZEA)
其中:FID
为文件地址(为fopen的返回值),FORMAT
为读取txt文件的格式,SIZEA
为读取的函数,如:[1 inf]
读取从第一行到最后一行
fclose
关闭文件
注意:这里的三个函数缺一不可(养成良好习惯,打开的文件要关闭)
fid=fopen('sj3.txt','r'); %只读
data=fscanf(fid,'编号:%d 长:%f 宽:%f 高:%f\n',[1 inf]); %按照读取文件的标准格式来写
fclose(fid); %关闭
data=reshape(data,4,length(data)/4)'; %重新按照格式排列
情况D.文件内容存在缺损(1)
在某些产品检测时,得到的数据可能存在缺损值,即某个标签下的值不存在。
例如sj4.txt
文件内容为:
123.1,754,124,12,57
13,754.5,124,12,57.7
23,754,124.2,12,
12,754,12,57.8
13,754,12.4,12,57
12.5,754,124,12,57.6
每行总共5个数字,分别代表5个属性,分别用逗号隔开。但是因为某些原因,存在缺损值,缺损值也是有逗号隔开了的。第三行缺第5个值,第四行缺第3个值
分析内容:这种缺损值,只是简单的数字值缺损,结构简单,缺损值少。
关键函数:importdata
data=importdata('sj4.txt'); %缺损的值将用NaN补全
情况E.文件内容存在缺损(2)
较之情况D,情况E的数据成分更加复杂。
例如sj5.txt
文件内容为:
10:21:54,123.1,754,124,57,10/24,a
10:21:56,13,754.5,124,12,57.7,21/54,b
10:21:58,23,754,124.2,12,20/64,
10:21:59,12,754,12,57.8,21/24,a
10:22:01,13,754,12.4,12,57,
10:22:02,12.5,754,124,12,57.6,22/54,b
总共存在8个属性,分别逗号隔开,属性1为时间 例如:10:21:54 10点21分54秒
分析内容:这是一组成分复杂且带有缺损值的文件,每组数据具有一定规律但又存在差异,这种情况也是MATLAB自带函数所不能轻易解决的,且若使用文件系统函数,也将变得非常繁琐,这里将使用另一种方式:正则表达式。百度’正则表达式’,其它地方也有很多的学习资料,但是大多数地方都存在一个特点:讲解得很全面。伴随之存在着缺点:内容繁多而且复杂,且我们没必要了解这么多。这里我就针对读取txt文件,只介绍我们需要的关键东西。
关键函数:regexp
x=regexp(str1,str2)
; 其中str1
表示原字符串,str2
表示分割标志符,x
表示匹配到的位置。
解决方案:
我们先分析一组数据
10:21:54,123.1,754,124,57,10/24,a
数据格式: 数据1,数据2,数据3,数据4,数据5,数据6,数据7,数据8
分析得知每个数据以逗号隔开,数据内容不限也可能为空,我们就可以以逗号为分割符将数据拆分开,如果相邻逗号位置相减为1,则该数据为空。
clear;clc;
data1=textread('cs20170704.txt','%s'); %读取出所有的内容
num=8; %总共8个数据
data=cell(length(data1),num); %创建最后的存储空间
str=','; %分割标志符
for n=1:length(data1)
addr=regexp(data1(n),str); %找到所有逗号位置
addr=cell2mat(addr); %regexp返回值为cell类型,此变为mat
data{n,1}=data1{n}(1:addr(1)-1); %数据1 时间不存在缺损,单独提出来
for m=2:num-1 %数据2-7
if addr(m)-addr(m-1)==1 %相邻逗号相减为1
data{n,m}=NaN; %空
else
data{n,m}=data1{n}(addr(m-1)+1:addr(m)-1); %数据非空(前面逗号-1)到(后面逗号+1)
end
end
if addr(7)==length(data1{n}) %数据8 最后一个数据单独提出来
data{n,8}=NaN; %空
else
data{n,8}=data1{n}(addr(7)+1:end); %数据非空
end
end
data
2. 读取二进制文件数据
mydataRead.m文件
function [data,state]=mydataRead(fileName,M,N)
fid=fopen(fileName,'rb');
if(fid>0)
[data,count]=fread(fid,[M,N],'float');
if(count==size(data,1)*size(data,2))
state=1;
else
state=-1;
end
end
fclose(fid);
end
rdata_bin.m文件
clear;
clc;
%%data format time s A m/s2(x,y,z) G degree/s(x,y,z)
%%read 64x bin data
file_path = 'data\';% path of bin data?
bin_path_list = dir(strcat(file_path,'*.bin'));%get all ?
bin_num = length(bin_path_list);%get number of bin data
%%
%read bin data to workspace
for i=1:bin_num
[data,state]=mydataRead([bin_path_list(i).folder bin_path_list(i).name],7,inf);
data=data';
namestr = ['T_AG_data_', num2str(i), '=', 'data', ';'];
eval(namestr);
end
3、读取图像文件
4、读取其他文件(Excel)
如果文件为Excel
格式,用xlsread
打开
例如sj6.txt
文件内容为:
% 先创建一个名为 sj6.xlsx 的 Excel 文件。
values = {1, 2, 3 ; 4, 5, 'x' ; 7, 8, 9};
headers = {'First','Second','Third'};
xlswrite('sj6.xlsx',[headers; values]);
% 从上面创建的 Excel 文件中读取特定范围的数据。
filename = 'sj6.xlsx';
sheet = 1;
xlRange = 'B2:C3';
subsetA = xlsread(filename,sheet,xlRange)
5、读取其他文件(.dat)可以参考.txt的读取方法
情况1:直接导入纯数字的.dat数据
在matlab中打开.dat文件,并将数据载入为二维矩阵
1、使用fopen和fread函数(或fscanf函数)
filein='路径\sj6.dat';
fid=fopen(filein,'r'); %打开数据文件
data=fread(fid,[x,y],'double'); %读取文件数据
fclose(fid); %关闭文件
filein='路径\sj6.dat';
fid=fopen(filein,'r'); %打开数据文件
x=fscanf(fid,'%g'); %读取文件数据
fclose(fid);
%得到的x数据为列向量
2、使用load、dlmread、importdata函数,部分情况下会报错,若报错建议使用fopen函数
Path = '路径\';
filename='路径\sj6.dat';
fid1 = load(filename);
fid2 = dlmread(filename);
fid3 = importdata(filename);
情况2:需要删除前几行多余文本,并去除逗号和最后一列标签项,保存数据
fid = fopen('路径\sj6.dat','rt');
%FormatString='%f %f %f %f %f %f %f %s';%取前8列数据
FormatString='%f %f %f %f %f %f %f %*[^\n]';%取前七列数据,最后一列标签去掉
% 注意:%*[^\n] 就是从当前直接跳到行尾。%*是一个跳过符号,表示跳过该位
N=348;%读取数据的行数
C=textscan(fid,FormatString,N,'HeaderLines',12,'delimiter',','); %跳过前12行,以逗号为数据的分隔符
C=cell2mat(C);%cell型数组转换为普通数组
fclose(fid);
[r,c]=size(C);
fid = fopen('路径\sj6.txt', 'wt'); %输出dat格式,将txt改一下即可。
for j=1:r
for m=1:c
fprintf(fid,'%4.2f\t',C(j,m));%保留两位小数点,包括小数点共4位
end
fprintf(fid,'\n');
end
fclose(fid);%保存为test文件
输出后txt文件:
0.49 0.29 0.48 0.50 0.56 0.24 0.35
0.07 0.40 0.48 0.50 0.54 0.35 0.44
0.56 0.40 0.48 0.50 0.49 0.37 0.46
0.59 0.49 0.48 0.50 0.52 0.45 0.36
0.23 0.32 0.48 0.50 0.55 0.25 0.35
0.67 0.39 0.48 0.50 0.36 0.38 0.46
0.29 0.28 0.48 0.50 0.44 0.23 0.34
0.21 0.34 0.48 0.50 0.51 0.28 0.39
0.20 0.44 0.48 0.50 0.46 0.51 0.57
…
参考博客:
博客1:在matlab中打开.dat文件,并将数据载入为二维矩阵
博客2:Matlab 读取dat文件(包含几行多余文本,数据带有数字和字符串,且以逗号分隔)
博客3:如何在matlab中打开一个.dat文件,并载入数据