www.gusucode.com > datastoreio工具箱 matlab源码程序 > datastoreio/+matlab/+io/+datastore/+splitreader/WholeFileCustomReadSplitReader.m
classdef WholeFileCustomReadSplitReader < matlab.io.datastore.splitreader.SplitReader %WHOLEFILECUSTOMREADSPLITREADER SplitReader that reads files with a custom read function. % % See also - matlab.io.datastore.WholeFileCustomReadDatastore % Copyright 2015 The MathWorks, Inc. properties (Hidden) % Split to read Split; % Read function ReadFcn; % Boolean to indicate if reading is complete ReadingDone = false; end properties (Access = protected, Transient) % Info struct fo this Split. Info; % Local filename. LocalFilename; % Is local temporary copy for hdfs file created. LocalCopyCreated = false; end methods (Access = protected) function copyFileToLocal(rdr) if rdr.LocalCopyCreated return; end basePath = tempname; while (true) [status, message, messageID] = mkdir(basePath); if ~status error(messageID, message); elseif isempty(messageID) break; end basePath = tempname; end [~, name, ext] = fileparts(rdr.Split.Filename); rdr.LocalFilename = fullfile(basePath, [name ext]); % Self open, Self closing stream! stream = matlab.io.datastore.internal.filesys.createStream(rdr.Split.Filename, 'r'); fileID = fopen(rdr.LocalFilename, 'w'); c = onCleanup(@()fclose(fileID)); uint8Values = read(stream, rdr.Split.FileSize, 'uint8'); fwrite(fileID, uint8Values); rdr.LocalCopyCreated = true; end function deleteIfLocalCopy(rdr) if ~rdr.LocalCopyCreated return; end localTempDir = fileparts(rdr.LocalFilename); if exist(localTempDir, 'dir') rmdir(localTempDir, 's'); end rdr.LocalCopyCreated = false; end function createLocalCopy(rdr) deleteIfLocalCopy(rdr); if strcmpi(rdr.Split.Filename(1:4), 'hdfs') copyFileToLocal(rdr); else rdr.LocalFilename = rdr.Split.Filename; end end function copiedObj = copyElement(obj) % Shallow copy copiedObj = copyElement@matlab.mixin.Copyable(obj); % Need a different copy to be created and deleted. copiedObj.LocalCopyCreated = false; copiedObj.ReadingDone = false; end end methods (Hidden) function pctg = progress(rdr) % Percentage of read completion between 0.0 and 1.0 for the split. pctg = double(rdr.ReadingDone); end function tf = hasNext(rdr) % Return logical scalar indicating availability of data tf = ~rdr.ReadingDone; end function [data, info] = getNext(rdr) % Return data and info as appropriate for the datastore createLocalCopy(rdr); try data = rdr.ReadFcn(rdr.LocalFilename); catch e iErrorOnReadFcn(e, rdr.ReadFcn, rdr.Split.Filename); end info = rdr.Info; rdr.ReadingDone = true; deleteIfLocalCopy(rdr); end function reset(rdr) % Reset the reader to the beginning of the split if isempty(rdr.Split) return; end % The checks for file existence is not needed (In case, % the file is deleted just before reading). We let the read % error for full file datastores. % initialize the info struct to be returned by readSplitData rdr.Info = struct('Filename', rdr.Split.Filename, ... 'FileSize', rdr.Split.FileSize); rdr.ReadingDone = false; end function delete(rdr) % Delete if there's a local copy, probably while erroring at % getNext(rdr). deleteIfLocalCopy(rdr); end end end function iErrorOnReadFcn(e, readFcn, filename) funcStr = func2str(readFcn); if ~isempty(funcStr) && ~isequal(funcStr(1), '@') funcStr = ['@', funcStr]; end % if the first element in the error stack is getNext(), this means % the nargout of readFcn is not at least 1. if strcmp( e.identifier, 'MATLAB:TooManyOutputs' ) && ~isempty(e.stack) stckName = e.stack(1).name; if isempty(e.stack(1).file) && numel(e.stack) > 1 % Grab the second element name, if the first element's file % is empty; this is the case for anonymous functions. stckName = e.stack(2).name; end if strcmp(stckName, [mfilename, '.getNext']) error(message('MATLAB:datastoreio:customreaddatastore:noOutputReadFcn', funcStr)); end end % Get the error message with the whole stack s = getReport(e); % Find the start of the stack for getNext() idx = strfind(s, mfilename); % Take the first match idx = idx(1); idx = regexp(s(1:idx), '\n'); % Take the last new line index idx = idx(end); % Remove all stack beneath getNext() s = strtrim(s(1:idx)); if ~isempty(s) error(message('MATLAB:datastoreio:customreaddatastore:readFcnError', funcStr, filename, s)); end throw(e); end