Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
onCleanup for closing files etc

Subject: onCleanup for closing files etc

From: Richard Crozier

Date: 7 Nov, 2011 15:00:28

Message: 1 of 6

I have a function which writes some files to disk. I would like to use onCleanup to delete these files if the function is interrupted. The names of the files are generated during program execution.

Is there any way to do this without using nested functions? Otherwise I don't see any way of passing the information to the cleanup function. The onCleanup method seems a bit limited in this respect.

Alternatively is there a way of updating the onCleanup object with new information? Can we overwrite the existing object? The documentation is a bit sparse here.

Thanks,

Richard

Subject: onCleanup for closing files etc

From: Steven_Lord

Date: 7 Nov, 2011 15:30:52

Message: 2 of 6



"Richard Crozier" <r.crozier@ed.ac.uk> wrote in message
news:j98rqc$r26$1@newscl01ah.mathworks.com...
> I have a function which writes some files to disk. I would like to use
> onCleanup to delete these files if the function is interrupted. The names
> of the files are generated during program execution.
>
> Is there any way to do this without using nested functions? Otherwise I
> don't see any way of passing the information to the cleanup function. The
> onCleanup method seems a bit limited in this respect.

fid = fopen('bench.dat', 'rt');
closeDataFile = onCleanup(@() fclose(fid));

The anonymous function captures the value of fid at the time the anonymous
function is created, and when it is executed by the onCleanup object, it
will close the bench.dat file.

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Subject: onCleanup for closing files etc

From: Richard Crozier

Date: 7 Nov, 2011 15:43:26

Message: 3 of 6

"Steven_Lord" <slord@mathworks.com> wrote in message <j98tjb$4jq$1@newscl01ah.mathworks.com>...
>
>
> "Richard Crozier" <r.crozier@ed.ac.uk> wrote in message
> news:j98rqc$r26$1@newscl01ah.mathworks.com...
> > I have a function which writes some files to disk. I would like to use
> > onCleanup to delete these files if the function is interrupted. The names
> > of the files are generated during program execution.
> >
> > Is there any way to do this without using nested functions? Otherwise I
> > don't see any way of passing the information to the cleanup function. The
> > onCleanup method seems a bit limited in this respect.
>
> fid = fopen('bench.dat', 'rt');
> closeDataFile = onCleanup(@() fclose(fid));
>
> The anonymous function captures the value of fid at the time the anonymous
> function is created, and when it is executed by the onCleanup object, it
> will close the bench.dat file.
>
> --
> Steve Lord
> slord@mathworks.com
> To contact Technical Support use the Contact Us link on
> http://www.mathworks.com


Sorry I should have been more explicit.

My function creates and deletes files, with different names, in a loop in the function. The names of these files are not known in advance, and change during the execution of the program. I want to ensure the most recently created set of file are deleted if there is an error or I hit CTRL+C.

The method you show does not allow me to delete files which I do not have a file identifier for before the creation of the onCleanup object. I also don't see how to provide such information to the onCleanup object.

Subject: onCleanup for closing files etc

From: Steven_Lord

Date: 7 Nov, 2011 17:57:36

Message: 4 of 6



"Richard Crozier" <r.crozier@ed.ac.uk> wrote in message
news:j98uau$73s$1@newscl01ah.mathworks.com...
> "Steven_Lord" <slord@mathworks.com> wrote in message
> <j98tjb$4jq$1@newscl01ah.mathworks.com>...
>>
>>
>> "Richard Crozier" <r.crozier@ed.ac.uk> wrote in message
>> news:j98rqc$r26$1@newscl01ah.mathworks.com...
>> > I have a function which writes some files to disk. I would like to use
>> > onCleanup to delete these files if the function is interrupted. The
>> > names of the files are generated during program execution.
>> >
>> > Is there any way to do this without using nested functions? Otherwise I
>> > don't see any way of passing the information to the cleanup function.
>> > The onCleanup method seems a bit limited in this respect.
>>
>> fid = fopen('bench.dat', 'rt');
>> closeDataFile = onCleanup(@() fclose(fid));
>>
>> The anonymous function captures the value of fid at the time the
>> anonymous function is created, and when it is executed by the onCleanup
>> object, it will close the bench.dat file.
>>
>> --
>> Steve Lord
>> slord@mathworks.com
>> To contact Technical Support use the Contact Us link on
>> http://www.mathworks.com
>
>
> Sorry I should have been more explicit.
>
> My function creates and deletes files, with different names, in a loop in
> the function. The names of these files are not known in advance, and
> change during the execution of the program. I want to ensure the most
> recently created set of file are deleted if there is an error or I hit
> CTRL+C.
>
> The method you show does not allow me to delete files which I do not have
> a file identifier for before the creation of the onCleanup object.

This is true. You need to have the information necessary to close the file
prior to creating the onCleanup object.

> I also don't see how to provide such information to the onCleanup object.

Anonymous function. Let's split the anonymous function creation and the
creation of the onCleanup object onto two lines for clarity.

for whichfile = 1:desiredNumberOfFiles
    dataNeededToCloseFile = myFileCreationFunction(whichfile);

    cleanupTask = @() closeTheFile(dataNeededToCloseFile);
    closeDataFile = onCleanup(cleanupTask);

    % work with the file

    delete(closeDataFile) % Force the onCleanup object to clean up and call
closeTheFile.
end

If the information necessary to close the file is available prior to the
file being opened, you can be even safer by creating the onCleanup object
BEFORE actually opening the file. For example, if whichfile is the only
information that closeTheFile needs to know in order to close the file, and
closeTheFile can handle closing a file that was not actually successfully
opened (TRYing to close the file and warning or doing nothing if an error is
thrown and trapped by CATCH), you can avoid this problem by swapping the
order of file creation and onCleanup creation.

for whichfile = 1:desiredNumberOfFiles
    cleanupTask = @() closeTheFile(whichfile);
    closeDataFile = onCleanup(cleanupTask);

    handleToFile = myFileCreationFunction(whichfile);

    % work with the file

    delete(closeDataFile) % Force the onCleanup object to clean up
end

Now, even if the attempt to create the file in myFileCreationFunction throws
an error, closeTheFile will be called (and will attempt to close the file,
doing nothing because the file was never successfully opened.)

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Subject: onCleanup for closing files etc

From: Richard Crozier

Date: 7 Nov, 2011 21:46:28

Message: 5 of 6

"Steven_Lord" <slord@mathworks.com> wrote in message <j9966f$5te$1@newscl01ah.mathworks.com>...
>
>
> "Richard Crozier" <r.crozier@ed.ac.uk> wrote in message
> news:j98uau$73s$1@newscl01ah.mathworks.com...
> > "Steven_Lord" <slord@mathworks.com> wrote in message
> > <j98tjb$4jq$1@newscl01ah.mathworks.com>...
> >>
> >>
> >> "Richard Crozier" <r.crozier@ed.ac.uk> wrote in message
> >> news:j98rqc$r26$1@newscl01ah.mathworks.com...
> >> > I have a function which writes some files to disk. I would like to use
> >> > onCleanup to delete these files if the function is interrupted. The
> >> > names of the files are generated during program execution.
> >> >
> >> > Is there any way to do this without using nested functions? Otherwise I
> >> > don't see any way of passing the information to the cleanup function.
> >> > The onCleanup method seems a bit limited in this respect.
> >>
> >> fid = fopen('bench.dat', 'rt');
> >> closeDataFile = onCleanup(@() fclose(fid));
> >>
> >> The anonymous function captures the value of fid at the time the
> >> anonymous function is created, and when it is executed by the onCleanup
> >> object, it will close the bench.dat file.
> >>
> >> --
> >> Steve Lord
> >> slord@mathworks.com
> >> To contact Technical Support use the Contact Us link on
> >> http://www.mathworks.com
> >
> >
> > Sorry I should have been more explicit.
> >
> > My function creates and deletes files, with different names, in a loop in
> > the function. The names of these files are not known in advance, and
> > change during the execution of the program. I want to ensure the most
> > recently created set of file are deleted if there is an error or I hit
> > CTRL+C.
> >
> > The method you show does not allow me to delete files which I do not have
> > a file identifier for before the creation of the onCleanup object.
>
> This is true. You need to have the information necessary to close the file
> prior to creating the onCleanup object.
>
> > I also don't see how to provide such information to the onCleanup object.
>
> Anonymous function. Let's split the anonymous function creation and the
> creation of the onCleanup object onto two lines for clarity.
>
> for whichfile = 1:desiredNumberOfFiles
> dataNeededToCloseFile = myFileCreationFunction(whichfile);
>
> cleanupTask = @() closeTheFile(dataNeededToCloseFile);
> closeDataFile = onCleanup(cleanupTask);
>
> % work with the file
>
> delete(closeDataFile) % Force the onCleanup object to clean up and call
> closeTheFile.
> end
>
> If the information necessary to close the file is available prior to the
> file being opened, you can be even safer by creating the onCleanup object
> BEFORE actually opening the file. For example, if whichfile is the only
> information that closeTheFile needs to know in order to close the file, and
> closeTheFile can handle closing a file that was not actually successfully
> opened (TRYing to close the file and warning or doing nothing if an error is
> thrown and trapped by CATCH), you can avoid this problem by swapping the
> order of file creation and onCleanup creation.
>
> for whichfile = 1:desiredNumberOfFiles
> cleanupTask = @() closeTheFile(whichfile);
> closeDataFile = onCleanup(cleanupTask);
>
> handleToFile = myFileCreationFunction(whichfile);
>
> % work with the file
>
> delete(closeDataFile) % Force the onCleanup object to clean up
> end
>
> Now, even if the attempt to create the file in myFileCreationFunction throws
> an error, closeTheFile will be called (and will attempt to close the file,
> doing nothing because the file was never successfully opened.)
>
> --
> Steve Lord
> slord@mathworks.com
> To contact Technical Support use the Contact Us link on
> http://www.mathworks.com

Ok, thanks, this is also ok, but effectively just repeating the original idea. I have several files I wish to manage concurrently, which are deleted and created in different orders. To be more specific, I am using a modified version of the 'multicore' package from the file exchange ( http://www.mathworks.com/matlabcentral/fileexchange/13775-multicore-parallel-processing-on-multiple-cores ) .

Using this method presumably means replacing every call to the file deletion code with the delete(closeDataFile), or whatever, and having many of these cleanup objects existing concurrently and being needed to be carefully kept track of in case I accidentally delete a file by destroying the wrong object at the wrong time etc. etc. etc.

I was really just kind of hoping there would be some kind of 'update' method for the onCleanup object that would allow me to pass in the new information, probably a structure containing the names of all the files currently existing and needing deleted if the function exits unexpectedly. I was imagining a situation like the following:

function dosomework()

    cleanupInfoStruct = struct('File1', '', 'File2', '');

    cleanupTask = @() onfinish(cleanupInfoStruct);
    ClnUpObj = onCleanup(cleanupTask);

     for whichfile = 1:desiredNumberOfFiles

         cleanupInfoStruct.File1 = myFileCreationFunction(whichfile);
         ClnUpObj.Update(@() onfinish(cleanupInfoStruct));

          % do other stuff

         if sometest
             cleanupInfoStruct.File2 = myFileCreationFunction(whichfile);
             ClnUpObj.Update(@() onfinish(cleanupInfoStruct));

             % do some stuff

             delete(cleanupInfoStruct.File2);
             cleanupInfoStruct.File2 = '';
             ClnUpObj.Update(@() onfinish(cleanupInfoStruct));
         end

         delete(cleanupInfoStruct.File1);
         cleanupInfoStruct.File1 = '';
         ClnUpObj.Update(@() onfinish(cleanupInfoStruct));
 
     end

end

function onfinish(cleanupInfoStruct)

     if ~isempty(cleanupInfoStruct.File1) && exist(cleanupInfoStruct.File1, 'file')
        delete(cleanupInfoStruct.File1);
    end

     if ~isempty(cleanupInfoStruct.File2) && exist(cleanupInfoStruct.File2, 'file')
        delete(cleanupInfoStruct.File2);
    end

end

This is still not ideal, but would be a bit easier than the way you suggest I think. Even better would be access to a variable passed to the cleanup function on exit, a bit like the UserData of a figure or something.

Thanks though.

Subject: onCleanup for closing files etc

From: Steven_Lord

Date: 8 Nov, 2011 14:59:02

Message: 6 of 6



"Richard Crozier" <r.crozier@ed.ac.uk> wrote in message
news:j99jjk$ntm$1@newscl01ah.mathworks.com...
> "Steven_Lord" <slord@mathworks.com> wrote in message
> <j9966f$5te$1@newscl01ah.mathworks.com>...

*snip*

> Ok, thanks, this is also ok, but effectively just repeating the original
> idea. I have several files I wish to manage concurrently, which are
> deleted and created in different orders. To be more specific, I am using a
> modified version of the 'multicore' package from the file exchange (
> http://www.mathworks.com/matlabcentral/fileexchange/13775-multicore-parallel-processing-on-multiple-cores )
> .
> Using this method presumably means replacing every call to the file
> deletion code with the delete(closeDataFile), or whatever, and having many
> of these cleanup objects existing concurrently and being needed to be
> carefully kept track of in case I accidentally delete a file by destroying
> the wrong object at the wrong time etc. etc. etc.
>
> I was really just kind of hoping there would be some kind of 'update'
> method for the onCleanup object that would allow me to pass in the new
> information, probably a structure containing the names of all the files
> currently existing and needing deleted if the function exits unexpectedly.
> I was imagining a situation like the following:

*snip*

> This is still not ideal, but would be a bit easier than the way you
> suggest I think. Even better would be access to a variable passed to the
> cleanup function on exit, a bit like the UserData of a figure or
> something.

There's no such "update" method, but it wouldn't be too difficult to build
your own onCleanup-like object:

classdef cleanupFiles < handle
    properties(Access='private')
        dataNeededToCleanup
    end
    methods
        function obj = cleanupFiles(data)
            obj.dataNeededToCleanup = data;
        end

        function update(obj, newdata)
            obj.dataNeededToCleanup = newdata;
        end

        function delete(obj)
            performCleanup(obj.dataNeededToCleanup);
        end
    end
end

I haven't tried this, but I believe it will work. You could of course make
this more flexible by also accepting a function handle to the function you
want to execute when the object is destroyed, but I'll leave that as an
exercise to the reader.

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us