deleting a file (C#) (sharing/etc) [resolved]

Started by
3 comments, last by Verg 15 years, 10 months ago
Hi, I'm running up against a dumb problem. It's probably a threading issue... but I need to find a way to discover whether another process is using a file before deleting it. System.IO.File.Delete("Filename") works most of the time, but occasionally the same process (different thread) still has a hold of the file I'm trying to delete. The code looks something like this: // pseudocode image_holder.setImage(newImage); System.IO.File.Delete(oldImage); This works in 99.9% of the cases, but sometimes it throws the "file is in use by another process" message. Of course, it's just the same process inside the "image_holder" class setting the image from the file. Long story short, how do I find out if a process is still using a file? Thanks. Chad [Edited by - Verg on June 9, 2008 4:48:24 PM]
my_life:          nop          jmp my_life
[ Keep track of your TDD cycle using "The Death Star" ] [ Verge Video Editor Support Forums ] [ Principles of Verg-o-nomics ] [ "t00t-orials" ]
Advertisement
When you open the file, do this:

FileStream fs = File.Open("MyTextFile.txt", FileMode.Open, FileAccess.Write, FileShare.None);


Then when you want to delete the the file, close it and delete it immediately.

fs.Close();File.Delete("MyTextFile.txt");


This works for me, but I don't think it is 100% guaranteed to work every time, because the OS might suspend your program after it closes the file but before you delete the file and another process may execute and open the same file during that time, however, the probability of this happening is very slim.

The main thing to notice in the call to open the file is the last parameter, which specifies that the file cannot be shared (i.e., it cannot be opened by another process). You need to be wary of the fact that when you specify "FileShare.None" as the sharing option, the call to open the file will throw an exception if the file has already been opened by another process, so you will need to handle this.

Hi Hugh,


This code isn't my own (it's the company's). They're simply creating the files like this:

Bitmap b = new Bitmap(... );// whatever goes in there
b.Save("filename");

I can't really change that too much. I believe an "Image" object is set from that, and then the temporary "b" object goes out of scope.

The "Image" object is stored inside an instance of another object (owned by the app). I get a ref to this "Image" from the Image property on this object, and then set the Image property to null. I call "Image.Dispose()" on the ref, and then it goes out of scope. In theory, this should kill all claims to the file by the system... but it isn't working.

It seems that sometimes the system is just unwilling to give access to this file to be deleted.

A brute force method would be to: simply create many files--a new file each time. But that's messy, and I'm not sure the system would automatically delete each of the files once the app closes.

Thanks for your insight



Chad
my_life:          nop          jmp my_life
[ Keep track of your TDD cycle using "The Death Star" ] [ Verge Video Editor Support Forums ] [ Principles of Verg-o-nomics ] [ "t00t-orials" ]
Some additional info for clarification:


The file just simply can't exist anymore; it has to be deleted each time through this portion of code. Reason? GDI+ cannot save to a file that already exists. In other words, Bitmap::Save(string) will fail if the file exists. The only sane way to prevent an exception there is to delete the file from the previous time through.

So there must be a 100% foolproof way to delete a file that is only in use by this process (possibly another thread). I'm suspecting the reason the file is locked at all has something to do with garbage collection in C#.

If we can't do this, then the brute force way (of simply creating many files and littering up the directory) is the only way around the problem. Obviously, this solution is not desired.

Thanks again for any input.


Chad
my_life:          nop          jmp my_life
[ Keep track of your TDD cycle using "The Death Star" ] [ Verge Video Editor Support Forums ] [ Principles of Verg-o-nomics ] [ "t00t-orials" ]
The issue has been resolved.

After setting the Image property on the object to null (inside a forced scope... i.e. "if(true)") I just forced garbage collection with these two lines:

System.GC.Collect();
System.GC.WaitForPendingFinalizers();

This gets rid of the previous instances of the bitmap (Image) object immediately, and allows us to delete the physical file using System.IO.File.Delete.

Thanks to all.



Chad
my_life:          nop          jmp my_life
[ Keep track of your TDD cycle using "The Death Star" ] [ Verge Video Editor Support Forums ] [ Principles of Verg-o-nomics ] [ "t00t-orials" ]

This topic is closed to new replies.

Advertisement