无法打开Matlab文件。

5

我有一个“.mat”文件,里面据说包含了一个[30720000x4 double]矩阵(加速度计的值)。但是当我试图在Matlab中使用“导入数据”打开此文件时,我会收到以下错误提示:

Error using load
Can't read file F:\vibration_exp_2\GR_UB50n\bearing1\GR_UB50n_1_2.mat.

Error using load
Unknown text on line number 1 of ASCII file
F:\vibration_exp_2\GR_UB50n\bearing1\GR_UB50n_1_2.mat
"MATLAB".

Error in uiimport/runImportdata (line 456)
                    datastruct = load('-ascii', fileAbsolutePath);

Error in uiimport/gatherFilePreviewData (line 424)
        [datastruct, textDelimiter, headerLines]= runImportdata(fileAbsolutePath,
        type);

Error in uiimport (line 240)
[ctorPreviewText, ctorHeaderLines, ctorDelim] = ...

文件大小为921MB,与我能够打开的其他文件相同。我也尝试使用Python打开该文件,但是没有成功。是否有任何建议?我使用的是MATLAB R2013b。

更多信息:

文件是如何创建的:

%% acquisition of vibration data
% input:
% sample rate in Hz (max. 51200 Hz, should be used as bearing 
% faults are high-frequent)
% time in seconds, stating the duration of the measurement 
% (e.g. 600 seconds = 10 minutes)
% filename for the file to be saved
%
% examples:
% data = DAQ(51200, 600, 'NF1_1.mat'); 
% data = DAQ(51200, 600, 'NF1_2.mat'); 
function data = DAQ(samplerate,time,filename) 

s = daq.createSession('ni'); % Creates the DAQ session
%%% Add the channels as accelerometer channels (meaning IEPE is turned on)
s.addAnalogInputChannel('cDAQ1Mod1','ai0','Accelerometer'); 
s.addAnalogInputChannel('cDAQ1Mod1','ai1','Accelerometer'); 
s.addAnalogInputChannel('cDAQ1Mod1','ai2','Accelerometer'); 
s.addAnalogInputChannel('cDAQ1Mod1','ai3','Accelerometer'); 
%s.addAnalogInputChannel('cDAQ1Mod2','ai0','Accelerometer'); 

s.Rate = samplerate;
s.NumberOfScans = samplerate*time; 
%%% Defining the Sensitivities in V/g
s.Channels(1).Sensitivity = 0.09478; %31965, top outer
s.Channels(2).Sensitivity = 0.09531; %31966, back outer
s.Channels(3).Sensitivity = 0.09275; %31964, top inner
s.Channels(4).Sensitivity = 0.09363; %31963, back inner

data = s.startForeground(); %Acquiring the data

save(filename, 'data');

更多信息:

当我使用简单的文本编辑器打开文件时,我可以看到许多不合理的字符,但也可以看到第一行:

MATLAB 5.0 MAT-FILE,平台:PCWIN64,创建于:2015年4月30日16:29:07


更多信息:

文件本身:https://www.dropbox.com/s/r7mavil79j47xa2/GR_UB50n_1_2.mat?dl=0 它的大小为921MB。

编辑:

如何恢复我的数据?

我尝试了这个,但出现了内存错误。 我还尝试了这个,但它没有起作用。


1
importdata不等于load。对于.mat文件,您应该单独使用load。显然,importdata在幕后使用了这个功能。 - Adriaan
我尝试了加载,但是出现了一个简单的错误,说它无法打开文件。(没有提供更多信息) - Olivier_s_j
我将把创建该文件的脚本添加到问题中。这是一个.mat文件,我有许多其他由同一脚本创建的文件可以正常工作。我认为该文件可能已经损坏,尽管文件大小没问题,因此我正在寻找一种恢复数据的方法。 - Olivier_s_j
MATLAB R2013b或MATLAB R2014a,我也尝试了两个版本来打开这个文件。目前这是唯一有问题的文件,我正在检查其他文件。 - Olivier_s_j
我觉得很奇怪,因为文件显示它是一个“MATLAB 5.0 MAT-FILE”。据说save命令在Matlab R2006b及更高版本中默认使用版本7.3。你在偏好设置中改变了什么吗? - horchler
显示剩余8条评论
3个回答

4

我恐怕不能为你带来太多好消息,但是还没有提到过。

.mat文件无法加载的原因是数据损坏了。导致它不可恢复的原因是存储方式。具体格式在MAT-File Format Documentation中有规定。所以我决定手动构造一个简单的读取器来读取你的.mat文件。

很明显,splitmat.m无法恢复任何东西,因为它基本上会将数据分成块,每个块存储一个变量,然而在这种情况下只存储了一个变量,因此只有一个块,这恰好是损坏的块。

在这种情况下,数据被存储为miCOMPRESSED,这是使用gzip压缩的正常matlab数组。(作为旁注,这似乎不适合“随机”振动数据。)这可能解释了先前对比完整数据更小的文件大小的评论,因为文件大小与内部存储的值完全匹配。

我提取了压缩文件并尝试以各种方式对其进行解压缩。基本上它是一个没有头部的'.gz',可以手动追加。不幸的是,在数据集开始附近似乎有一个损坏的块。我绝不是gzip的专家,但据我所知,字典(或解密密钥)是动态存储的,这使得块损坏后所有数据都无用。如果你真的渴望,似乎有一种方法可以恢复数据,即使在数据损坏的点之后,但这种方法非常耗时。此外,验证这些部分的数据的唯一方法是手动检查,这在你的情况下可能会非常困难。

以下是我用来提取.gz文件的代码,所以如果你想试试,这可能会帮助你入门。如果你成功解密了数据,可以按照MAT-File Format,13f中描述的方式读取它。

corrupted_file_id = fopen('corrupt.mat','r');
%% some header data
% can be skipped replacing this block with
% fread(id,132);

%header of .mat file
header_text = char(fread(corrupted_file_id,116,'char')');
subsystem_data_offset = fread(corrupted_file_id,8,'uint8');
version = fread(corrupted_file_id,1,'int16');
endian_indicator = char(fread(corrupted_file_id,2,'int8')');
data_type = fread(corrupted_file_id,4,'uint8'); 
%data_type is 15, so it is a compressed matlab array


%% save te content
data_size = fread(corrupted_file_id,1,'uint32');
gz_file_id = fopen('compressed_array.gz','w');
% first write a valid gzip head
fwrite(gz_file_id,hex2dec('1f8b080000000000'),'uint64',0,'b');

% then write the data sequentialy 
step = 1:1e3:data_size;% 1MB steps
for idx = step
fwrite(gz_file_id,fread(corrupted_file_id,1e3,'uint8'));
end
step = step(end):data_size;% 1B steps
for idx = step
    fwrite(gz_file_id,fread(corrupted_file_id,1,'uint8'));
end
fclose(gz_file_id);
fclose(corrupted_file_id);

1

好的,我尝试了这个工具,它显示文件已损坏。 - Olivier_s_j
1
@Ojtwist,你能否确认一下提供文件的人,数据保存没有因为磁盘已满、磁盘配额不足或者电源故障而停止了吗? - user2271770
@Ojtwist 你应该查看 MATLAB Central 论坛,它们涵盖了很多问题。例如:http://www.mathworks.com/matlabcentral/answers/98890-how-do-i-recover-data-from-a-corrupt-mat-file - user2271770
@Ojtwist 但是你能确认文件已经成功生成了吗? - user2271770
据说是的。我可以确定的是.mat文件中的变量"data"具有正确的尺寸。此外,该文件的大小正确(应该约为920 MB,确实如此)。因此,在我看来,应该能够恢复一些数据... - Olivier_s_j

0
文件大小(索引超出范围)似乎是一个问题。Octave应该读取.mat文件,但会出现错误。
memory exhausted or requested size too large for range of Octave's index type

为了找出问题所在,您可能需要编写一个测试程序,该程序位于MatLab之外,在那里您可以更好地控制内存管理。这里有一些示例here,包括如何在自己的平台上构建它们的说明。这些独立程序可能不会有相同的内存问题。程序matdgns.c专门用于检查.mat文件中的错误。

很想听听为什么会被踩。matdgns.c程序是专门用于诊断.MAT文件的,因此它是相关的,而尝试使用Octave而不是Python打开.MAT文件(正如OP所做的那样)是一个合理的想法。 - alle_meije

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接