Loren on the Art of MATLAB

Turn ideas into MATLAB

Note

Loren on the Art of MATLABhas been retired and will not be updated.

Keeping Things Tidy

In the past, when you opened a file in a MATLAB program, you had to keep track of it so you could close it under all possible conditions, i.e., if reading or processing failed, worked partially, or worked perfectly. You could achieve this using thecatchblock after atry. But you still might have to know before closing the file if everything you wanted to do was complete. Code could easily get awkward and buggy if there were lots of code paths to watch out for. WithR2008a, you can use theonCleanupclass to help you out more cleanly.

Contents

Example Code - Open File

Here's the start of a file I've written that opens up an image file for reading, usingfopen.

typeopenImageFile0
function openImageFile0 % openImageFile Open an image file. fd = fopen('pout.tif');

If I run it, you can see that I never close the file.

openImageFile0() fids = fopen('all') filename = fopen(fids(1)); filename(end-30:end)
支撑材s = 3 ans = toolbox\images\imdemos\pout.tif

Tidy up now.

fclose(fids(1));

Example Code - Manage Open, Close, and Errors Using try/catch

现在让我们来看看另一个版本的代码will close the file it opens before returning.

typeopenImageFile1
function openImageFile1 % openImageFile1 Open/process file while ensuring file is % closed on finish. try fd = fopen('pout.tif'); if fid == -1 error('LS:NoImageFile','no such file') end doMoreHere(fd); catch Ex disp('Can not read file') end if fid ~= -1 fclose(fid); end

You can see that, even withtry/catch, since I always want to close the image file, I have some extra logic at the end of the file. And I have to be careful to know whether the error occurs because the file was never opened, or if instead the error occurs in later processing.

Example Code - Use onCleanup to Ensure File Closes

这里有一个文件大致相当于第一one, but it ensures that the image file is closed when the function is finished running.

typeopenImageFile2
function openImageFile2 % openImageFile2 Open an image file for further processing. % Note: this doesn't do what you want, since the file will % be closed after completing and the file identifier won't % be active for use upon completion. fd = fopen('pout.tif'); C = onCleanup(@()fclose(fd));

To see that this works we first check that no files are open, run the function, and make sure that no files are open afterwards.

fb = fopen('all'); openImageFile2() fp = fopen('all'); noFilesOpen = isequal(fp,fb,[])
noFilesOpen = 1

Example Code - Use onCleanup and Process After Opening the File

Let's see the next version of the file.

typeopenImageFile3
function fd = openImageFile3 % openImageFile3 Open an image file for further processing. % Note: this doesn't do what you want, since the file will % be closed after completing and the file identifier won't % be active for use upon completion. fd = fopen('pout.tif'); C = onCleanup(@()fclose(fd));

This function returns the file identifier, but as we'll see, the file is closed once the function returns. This means that any processing/reading we were planning to do with the file after calling the open function will not work (since the file will no longer be open).

fb = fp; fid = openImageFile3() fp = fopen('all'); noFilesOpen = isequal(fp,fb,[])
支撑材= 3 noFilesOpen = 1

Even though支撑材is returned from the function call, the file is no longer open. This is because theonCleanupobjectCis cleared from existence onceopenImageFile3completes execution.

Example Code - Use onCleanup and Process and Close File on Completion

Here's the last version of the file for this blog. As long as you call it with 2 outputs, you are good to go.

typeopenImageFile4
function [fd, C] = openImageFile4 % openImageFile4 Open an image file for further processing. % Note: this does what you want, provided you call the % function with both output arguments. When you are done % cleaned up and the onCleanup object will trigger the file % closing. % Don't even open file if function isn't called with 2 outputs. if nargout < 2 error('LS:MustHave2Outputs','must call with 2 outputs') end fd = fopen('pout.tif'); C = onCleanup(@()fclose(fd));

This version returns the file identifier and theonCleanupobject. Once you have processed your file, simply clear theonCleanupobject and the file will close.

To see how this might work, we call it from our function that does the processing.

typerun4
函数y = run4 % run4过程一个图像文件。[fid,C] = openImageFile4(); blocksize = 100; y = []; while something dat = fread(fid,count); y = doSomething(y,dat); something = update(something); end

You can see thatrun4calls openImageFile4, and then does the required processing. BecauseCwill vanish oncerun4completes, the file will be closed.

Other Uses?

TheonCleanupobject allows you to more cleanly manage resources such as closing files, closing windows (e.g., last week someone mentioned managing instances ofwaitbar), managing switching directories. What uses do you foresee for theonCleanupobject in your work? Let me knowhere.




Published with MATLAB® 7.6

|