我在用
fid = fopen('fgfg.txt');
Run Code Online (Sandbox Code Playgroud)
打开一个文件.
有时在我设法关闭文件之前发生错误.在关闭Matlab之前,我无法对该文件做任何事情.
如果发生错误,如何关闭文件?
And*_*ein 49
首先,您可以使用该命令
fclose all
Run Code Online (Sandbox Code Playgroud)
其次,您可以使用try-catch块并关闭文件句柄
try
f = fopen('myfile.txt','r')
% do something
fclose(f);
catch me
fclose(f);
rethrow(me);
end
Run Code Online (Sandbox Code Playgroud)
还有第三种方法,它要好得多.Matlab现在是一个带垃圾收集器的面向对象语言.您可以定义一个自动处理其生命周期的包装器对象.
因为在Matlab中有可能以这种方式调用对象方法:
myObj.method()
并以这种方式:
方法(MyObj中)
您可以定义一个模仿所有相关文件命令的类,并封装生命周期.
classdef safefopen < handle
properties(Access=private)
fid;
end
methods(Access=public)
function this = safefopen(fileName,varargin)
this.fid = fopen(fileName,varargin{:});
end
function fwrite(this,varargin)
fwrite(this.fid,varargin{:});
end
function fprintf(this,varargin)
fprintf(this.fid,varargin{:});
end
function delete(this)
fclose(this.fid);
end
end
end
Run Code Online (Sandbox Code Playgroud)
该删除操作员利用Matlab自动调用.(你需要包装更多的功能,(fread,fseek等)).
所以现在你有了安全句柄,无论你丢失了它的范围还是发生了错误,它都会自动关闭文件.
像这样使用它:
f = safefopen('myFile.txt','wt')
fprintf(f,'Hello world!');
Run Code Online (Sandbox Code Playgroud)
而且无需关闭.
编辑:
我只想到包装fclose()什么都不做.它可能对向后兼容性很有用 - 对于使用文件ID的旧函数.
编辑(2):关注@AndrewJanke好评,我想通过在fclose()上抛出错误来改进删除方法
function delete(this)
[msg,errorId] = fclose(this.fid);
if errorId~=0
throw(MException('safefopen:ErrorInIO',msg));
end
end
Run Code Online (Sandbox Code Playgroud)
Mar*_*arc 29
您可以尝试使用ML添加的非常简洁的"功能" onCleanup.Loren Shure在添加时对其进行了完整的写作.它是一个用清理代码实例化的类,然后当它超出范围时执行 - 即当它出错时,或者函数结束时.使代码非常干净.这是Andrey在上面的类的通用版本.(顺便说一句,对于像打外部数据源这样的复杂任务,定制类肯定是要走的路.)
从帮助:
function fileOpenSafely(fileName)
fid = fopen(fileName, 'w');
c = onCleanup(@()fclose(fid));
functionThatMayError(fid);
end % c executes fclose(fid) here
Run Code Online (Sandbox Code Playgroud)
基本上,你给它一个函数句柄(在这种情况下@()fclose(fid))它在超出范围时运行.
您的清理代码在抛出错误或正常退出时执行,因为您退出fileOpenSafely并c超出范围.
不需要try/catch或有条件的代码.