📄 transio.m
字号:
function [varargout] = transio(varargin)
% transio (Object Class)
%
% FORMAT: tio_obj = transio(file, endian, class, offset, size);
%
% Input fields:
%
% file filename where data is stored in
% endian endian type (e.g. 'le', or 'ieee-be')
% class numerical class (e.g. 'uint16', 'single')
% offset offset within file (in bytes)
% size size of array in file
%
% Output fields:
%
% tio_obj transio object that supports the methods
% - subsref : tio_obj(I) or tio_obj(IX, IY, IZ)
% - subsasgn : same as subsref
% - size : retrieving the array size
% - end : for building relative indices
% - display : showing information
%
% Note 1: enlarging of existing files (if the array is the last element
% in the file) can be done by adding a (class-independent) sixth
% parameter to the call.
%
% Note 2: both subsref and subsasgn will only work within the existing
% limits; growing of the array as with normal MATLAB variables
% is *NOT* supported--so tio_obj(:,:,ZI) = []; will *NOT* work!
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Version: v0.7b
% Build: 7082923
% Date: Aug-29 2007, 11:26 PM CEST
% Author: Jochen Weber, Brain Innovation, B.V., Maastricht, NL
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% This Class provides transparent IO access to files that store large
% variables at certain place.
%
% When accessed, the file is opened and closed each time! Since MATLAB
% does not offer destructors, it is virtually impossible to keep track
% of open files!
%
% The construction of a transio object can be done with a syntax of:
%
% tio = transio(file, endian, class, offset, size [, enlarge]);
%
% When the fifth argument is not given, transio will issue an error
% if the filesize is not sufficient.
% declare persistent stored variable
persistent transio_singleton;
% check class initialization
if isempty(transio_singleton) || ...
~isstruct(transio_singleton) || ...
~transio_singleton.is_initialized
% initialize persistent struct
transio_singleton = struct;
transio_singleton.is_initialized = false;
% perform init commands
transio_singleton.validclasses = struct( ...
'double', 8, ...
'int16', 2, ...
'int32', 4, ...
'int64', 8, ...
'int8', 1, ...
'single', 4, ...
'uint16', 2, ...
'uint32', 4, ...
'uint64', 8, ...
'uint8', 1 ...
);
transio_singleton.validcnames = fieldnames(transio_singleton.validclasses);
transio_singleton.validendian = struct( ...
'be', false, ...
'le', true, ...
'ieee_be', false, ...
'ieee_le', true, ...
'ieeebe', false, ...
'ieeele', true ...
);
transio_singleton.validenames = fieldnames(transio_singleton.validendian);
% say we are initialized
transio_singleton.is_initialized = true;
end
% check arguments > object creation call
if nargin > 4 && ...
ischar(varargin{1}) && ...
~isempty(varargin{1}) && ...
(exist(varargin{1}(:)', 'file') == 2 || ...
nargin > 5) && ...
any(strcmp(makelabel(lower(varargin{2}(:)')), transio_singleton.validenames)) && ...
any(strcmpi(varargin{3}(:)', transio_singleton.validcnames)) && ...
isa(varargin{4}, 'double') && ...
numel(varargin{4}) == 1 && ...
~isinf(varargin{4}) && ...
~isnan(varargin{4}) && ...
fix(varargin{4}) == varargin{4} && ...
varargin{4} >= 0 && ...
isa(varargin{5}, 'double') && ...
~isempty(varargin{5}) && ...
numel(varargin{5}) == length(varargin{5}) && ...
length(varargin{5}) < 32 && ...
~any(isinf(varargin{5}) | isnan(varargin{5}) | fix(varargin{5}) ~= varargin{5}) && ...
~any(varargin{5} < 1 | varargin{5} > 2147483648)
% make absolute filename
[isabs, filename] = isabsolute(varargin{1}(:)');
% open the file
try
fid = fopen(filename, 'a+');
if fid < 1
error('INVALID_FID');
end
catch
error( ...
'transio:ErrorOpeningFile', ...
'Error opening file ''%s''.', ...
filename ...
);
end
% calculate most significant position
lnd = transio_singleton.validendian.(makelabel(lower(varargin{2}(:)')));
cls = lower(varargin{3}(:)');
csz = transio_singleton.validclasses.(cls);
obs = varargin{5}(:)';
while ~isempty(obs) && ...
obs(end) == 1
obs(end) = [];
end
while length(obs) < 2
obs(end+1) = 1;
end
obs = obs(:)';
ofs = varargin{4};
msp = ofs + csz * prod(obs);
% go to end position and check size
fseek(fid, 0, 1);
fsz = ftell(fid);
% file too short and no enlarging
if fsz < msp && nargin < 6
% give an error
error( ...
'transio:FileTooShort', ...
'The file is too short to read/write the data.' ...
);
% enlarging
elseif fsz < msp
% create array to write
war = uint8(0);
war(1:1048576) = war(1);
tfsz = fsz;
mspf = msp - 1048576;
try
while tfsz < mspf
fwrite(fid, war, 'uint8');
tfsz = tfsz + 1048576;
end
fwrite(fid, war(1:(msp - tfsz)), 'uint8');
% check again
fseek(fid, 0, 1);
if ftell(fid) ~= msp
error('ENLARGE_ERROR');
end
catch
error( ...
'transio:ErrorEnlargingFile', ...
'Error while enlarging the file.' ...
);
end
end
% close file again, we don't keep it open anyway
fclose(fid);
% build object
sobj.FileName = filename;
sobj.LittleND = lnd;
sobj.DataType = cls;
sobj.TypeSize = csz;
sobj.IOOffset = ofs;
sobj.DataDims = obs;
obj = builtin('class', sobj, 'transio');
% return object
varargout{1} = obj;
% object creation
elseif nargin > 1 && ...
isa(varargin{1}, 'double') && ...
ischar(varargin{2}) && ...
~isempty(varargin{2}) && ...
strcmp(makelabel(varargin{2}(:)'), varargin{2}(:)')
% what action to perform
switch lower(varargin{2}(:)')
case {'makeobject'}
if isstruct(varargin{3}) && ...
numel(varargin{3}) == 1 && ...
length(fieldnames(varargin{3})) == 6 && ...
all(strcmp(fieldnames(varargin{3}), { ...
'FileName'; ...
'LittleND'; ...
'DataType'; ...
'TypeSize'; ...
'IOOffset'; ...
'DataDims'}))
varargout{1} = builtin('class', varargin{3}, 'transio');
end
otherwise
if ~any(strcmpi(transio_singleton.validcnames, varargin{2}(:)'))
error( ...
'transio:BadArgument', ...
'Unknown action string: %s.', ...
varargin{2}(:)' ...
);
end
varargout{1} = ...
transio_singleton.validclasses.(lower(varargin{2}(:)'));
end
% default constructor
elseif nargin == 0
varargout{1} = builtin('class', struct( ...
'FileName', 'NONE', ...
'LittleND', 1, ...
'DataType', 'double', ...
'TypeSize', 8, ...
'IOOffset', 0, ...
'DataDims', [0, 0]), 'transio');
% otherwise give an error
else
error( ...
'transio:BadArgument', ...
'Invalid combination of arguments.' ...
);
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -