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
If you have any control over the process that does the writing in, then consider augmenting it so the following process happens:
You can look for ".done" files as the trigger to start processing a file. Again, this will only work if you have any way to modify the process that does the writing in of files.
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.
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
}
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.
Use the System.IO.FileSystemWatcher to determine files that are changed.
Open them in an exclusive reader (FileMode.Read) in make the copies, and catch the exception should this fail (because someone else has it open for writing).
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.