Created
November 13, 2015 11:57
-
-
Save eruffaldi/b1415dc0f1e9aebb9260 to your computer and use it in GitHub Desktop.
MATLAB Simulink Level 4 MAT truncated file fix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% quick and dirty file fixer for MATLAB Simulink Level 4 | |
% | |
% Limitations: only double, needs to support other types and complex data | |
% Limitations: cannot cut file when spurious, needs to append a dummy | |
% variable (dummy) | |
% | |
% Emanuele Ruffaldi | |
% | |
% See: http://it.mathworks.com/help/pdf_doc/matlab/matfile_format.pdf | |
function fixlevel4(filename,dofix) | |
if dofix | |
mode = 'r+b'; | |
else | |
mode = 'rb'; | |
end | |
f=fopen([filename '.mat'], mode); | |
fseek(f,0,'eof'); % | |
s = ftell(f); % file size | |
fseek(f,0,'bof'); | |
while feof(f) == 0 | |
% 20 bytes header | |
hp = ftell(f); | |
h2=fread(f,5,'int32')'; | |
if isempty(h2) | |
break | |
end | |
if length(h2) < 5 | |
disp('need to close file') | |
if dofix | |
fseek(f,hp,'bof'); | |
remainder = s-hp-5*4-5; | |
contentsize = max(1,remainder); | |
tmp = zeros(contentsize,1); | |
h3 = [0,1,contentsize,0,5]; % dummy header 1 by contentsize | |
fwrite(f,h3,'int32'); | |
fwrite(f,'dummy','uint8'); % name | |
fwrite(f,tmp,'double'); % data | |
end | |
break | |
end | |
rows = h2(2); | |
cols = h2(3); | |
name = char(fread(f,h2(5),'uint8'))' | |
itemsize = 8; | |
if h2(1) ~= 0 | |
error('only double supported'); | |
end | |
if cols == 0 | |
p = ftell(f); % current position | |
cols = floor((s-p)/itemsize/rows) | |
remainder = (s-p)-cols*rows*itemsize | |
if dofix | |
h2(3) = cols; | |
fseek(f,hp,'bof'); | |
fwrite(f,h2,'int32'); | |
break | |
% NOT WORKING | |
% cannot resize file, so append spurious | |
hs = 5*4; | |
contentsize = max(1,remainder); | |
tmp = zeros(contentsize,1); | |
h3 = [0,1,contentsize,0,5]; % dummy header 1 by contentsize | |
fwrite(f,h3,'int32'); | |
fwrite(f,'dummy','uint8'); % name | |
fwrite(f,tmp,'double'); % data | |
else | |
newheader = h2 | |
end | |
break | |
else | |
skip = rows*cols*itemsize; | |
fseek(f,skip,'cof'); | |
end | |
end | |
fclose(f) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment