Andrey решение above действительно лучший подход к решению этой проблемы. Я просто хотел добавить, что исключение исключения в методе delete()
может быть проблематичным, если вы имеете дело с массивами объектов safefopen
. Во время уничтожения такого массива MATLAB будет вызывать delete()
для каждого элемента массива и, если возникнет какая-либо ошибка delete()
, вы можете получить оставшиеся открытые дескрипторы файлов. Если вам действительно нужно знать, что что-то пошло не так во время разрушения, то выдача предупреждения будет лучшим вариантом ИМХО.
Для тех, лень писать все методы пересылки каждому MATLAB встроенной команды, которая использует дескрипторы файлов, вы можете рассмотреть простой вариант перегрузки метода subsref
для класса safefopen
:
methods(Access=public)
function varargout = subsref(this, s)
switch s(1).type
case '.'
if numel(s) > 1,
feval(s(1).subs, this.fid, s(2).subs{:});
else
feval(s(1).subs, this.fid);
end
% We ignore outputs, but see below for an ugly solution to this
varargout = {};
otherwise
varargout{1} = builtin('subsref', this, s);
end
end
end
Эта альтернатива использует несколько ugly feval
, но имеет преимущество в работе, даже если ребята MATLAB (или самостоятельно) решили добавить новые функции, которые связаны с файловыми дескрипторами, или если число/порядок входных аргументов для данной функции изменится. Если вы решили пойти на subsref
альтернатив, то вы должны использовать класс safefopen
так:
myFile = safefopen('myfile.txt', 'w');
myFile.fprintf('Hello World!');
EDIT: Недостатком subsref
решения является то, что он игнорирует все аргументы вывода. Если вам нужны выходные аргументы, то вам придется ввести еще некоторые уродства:
methods(Access=public)
function varargout = subsref(this, s)
if nargout > 0,
lhs = 'varargout{%d} ';
lhs = repmat(lhs, 1, nargout);
lhs = ['[' sprintf(lhs, 1:nargout) ']='];
else
lhs = '';
end
switch s(1).type
case '.'
if numel(s) > 1,
eval(...
sprintf(...
'%sfeval(''%s'', this.fid, s(2).subs{:});', ...
lhs, s(1).subs) ...
);
else
eval(...
sprintf('%sfeval(''%s'', this.fid);', ...
lhs, s(1).subs) ...
);
end
otherwise
varargout{1} = builtin('subsref', this, s);
end
end
end
И тогда вы могли бы сделать что-то вроде:
myFile = safefopen('myfile.txt', 'w');
count = myFile.fprintf('Hello World!');
[filename,permission,machineformat,encoding] = myFile.fopen();
Близко связанные: [Как вы обрабатываете ресурсы в MATLAB безопасным образом? (например, «try ... finally»)] (http://stackoverflow.com/q/1098149/52738) – gnovice