Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test if a file is currently being written to

Tags:

c#

.net

I have an application that must check a folder and read any files that are copied into it. How do I test if a file in that folder is currently being written to? I only want to read files that have had all their data written to them and are closed.

like image 322
willsan Avatar asked Mar 25 '10 13:03

willsan


People also ask

How do you tell if a file is being written to?

If your files have a known naming convention, run an lsof <filename> against it to check if it is indeed being used by a process. If it isn't, lsof will return a non-zero return code. Please note: If you want to check if the file is being written to by another user, you'll need to run lsof (or fuser ) as root .

Can you read a file that is being written to?

Most likely, you'll have to make your program open the file, read a small chunk, close the file, and then wait for a bit before reading again. Even then, there's no guarantee that you won't have the file open when the writing process tries to write.


6 Answers

It ain't clean, but it works:

try
{
    using (Stream stream = new FileStream("File.txt"))
    {
    }
} 
catch 
{
    // Check if file is in use (or whatever else went wrong), and do any user communication that you need to
}

I don't particularly like using exceptions as conditions, but as far as I know this is about the easiest and best (and only reliable) way to do this.

like image 53
Kyle Rosendo Avatar answered Sep 30 '22 16:09

Kyle Rosendo


Perhaps opening the file exclusively like this -

System.IO.File.Open(PathToFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None);

That could be placed in a loop with a try/catch until its successful.

like image 25
kragan Avatar answered Sep 30 '22 16:09

kragan


Catching exception is expensive you should try to use this:

http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx

There's a super clear example on the msdn page. That'll give you nice events on change, created, delete, renamed.

copy the file into the folder and rename when your done catch the rename event and your sure your not reading files that aren't finished yet.

Or you could catch the change events until (this is tricky) they aren't fired anymore.

like image 29
albertjan Avatar answered Sep 30 '22 17:09

albertjan


The only thing I can think of is that a file lock will be put on the file while it is being written to, therefore preventing you from writing to it (throwing a System.IO exception of file being locked by another process), but this is not foolproof. For example, the file could be written to in chunks by opening and closing the file for each chunk.

So you could do this with a try/catch block:

try
{
   //opening the file
} 
catch(IOException ex)
{
   // file is open by another process
}
like image 23
Bryan Denny Avatar answered Sep 30 '22 17:09

Bryan Denny


The file that is written to will typically have write locks on it so if you try to open it for write, you'll fail; but OTOH you may have a process that opens, writes, and closes the file - then repeats. I think the simplest and safest way would be simply to check for files that were written to recently, but not TOO recent (e.g. not in the last 2 seconds or so)

[l.e.] Another point to consider is that if you have a process that writes data in chunck (open-write-close), and you get an exclusive lock for the file (to check that the file is no longer used) - than your external process will fail. I think it's far better to check the timestamps, and only get the exclusive lock after you're reasonably sure that the other process finished writing.

like image 43
Virgil Avatar answered Sep 30 '22 16:09

Virgil


When you open it with System.IO.File.OpenWrite(filename), it should throw IOException.

So, in a try catch, the code being executed in the catch block should tell you the file was open.

like image 28
David Fox Avatar answered Sep 30 '22 15:09

David Fox