【问题标题】:Can't open matlab filematlab文件打不开
【发布时间】:2016-02-15 01:11:27
【问题描述】:

我有一个“.mat”文件,据说包含一个 [30720000x4 双] 矩阵(来自加速度计的值)。当我尝试在 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,创建于:4 月 30 日星期四 2015 年 16:29:07


更多信息: 文件本身:https://www.dropbox.com/s/r7mavil79j47xa2/GR_UB50n_1_2.mat?dl=0 它是 921MB。


编辑:

如何恢复我的数据?

我试过this,但出现内存错误。 我也试过this,但没用。

【问题讨论】:

  • importdata!=load。对于 .mat 文件,您应该单独使用 load。显然importdata 在后台使用了这个。
  • 好吧,我也试过加载,然后我收到一个简单的错误,说它无法打开文件。 (没有提供更多信息)
  • 这个文件是从哪里来的?它实际上是一个*.mat 文件吗?
  • 我会将创建文件的脚本添加到问题中。它是一个 .mat 文件,我有许多其他文件由相同的脚本创建,它们确实有效。我认为该文件在某种程度上已损坏,但是文件大小还可以,所以我正在寻找一种方法来恢复我的数据。
  • 用于保存这些文件的 MATLAB 版本是否与您使用的版本相同?这是唯一有问题的文件吗? load(filename, '-mat') 会发生什么?

标签: matlab


【解决方案1】:

恐怕我不能为你已经知道的事情添加很多好消息,但还没有被提及。

无法加载 .mat 文件的原因是数据损坏。使它“不可恢复”的是它在内部存储的方式。确切的格式在MAT-File Format Documentation 中指定。所以我决定手动构建一个简单的阅读器来专门阅读你的 .mat 文件。

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

在这种情况下,数据存储为miCOMPRESSED,这是一个使用 gzip 压缩的普通 matlab 数组。 (作为旁注,这似乎不太适合“随机”振动数据。)这可以解释以前的 cmets 关于文件大小比完整数据更小的问题,因为文件大小与内部存储的值完全匹配。

我提取了压缩档案并尝试以多种方式解压缩它。基本上它是一个没有标题的“.gz”,可以手动附加。不幸的是,在数据集的开头附近似乎有一个损坏的块。我绝不是 gzip 方面的专家,但据我所知,字典(或解密密钥)是动态存储的,这使得从块被破坏的那一刻起,所有数据都变得无用。如果您真的很急切,那么即使在数据损坏的点后面似乎也有a way to recover data,但这种方法非常耗时。此外,验证这些部分的数据的唯一方法是手动检查,在您的情况下这可能非常困难。

以下是我用来提取 .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);

【讨论】:

    【解决方案2】:

    文件的大小(索引超出范围)似乎是个问题。 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 完成)是一个合乎逻辑的想法。
    【解决方案3】:

    要回答字面意思的问题,我的建议是首先确保文件没问题。 File Exchange 上的这个工具显然知道如何从 V5 (R8) 版本开始诊断损坏的 .MAT 文件:

    http://www.mathworks.com/matlabcentral/fileexchange/6893-matcat-mat-file-corruption-analysis-tool

    【讨论】:

    • 好吧,我试过这个工具,它说文件已损坏。
    • @Ojtwist 能否与提供文件的人确认数据保存不是因磁盘已满、磁盘配额不足或电源故障而停止?
    • @Ojtwist 您应该查看 MATLAB Central 论坛,它们涵盖了很多问题。例如:mathworks.com/matlabcentral/answers/…
    • @Ojtwist 但是你能确认文件生成成功了吗?
    • 应该是的。我可以肯定地说.mat文件中的变量“数据”具有正确的尺寸。此外,该文件的大小合适(应该是 920 MB 左右)。所以在我看来,一些数据应该是可恢复的……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-01
    相关资源
    最近更新 更多