file system events (FileSystemWatcher)

A

Allen Anderson

I'm trying to figure out a way to catch when a file has been written
to a directory. I currently have it where I can catch when the file
begins writing, but this isn't helpful as I need to know when its
done. Does anyone know the right combination of flags to use to catch
when the file has been written and closed? (here is my current code).

// member variable
FileSystemWatcher watcher = new FileSystemWatcher();


// init code
watcher.Path = @"c:\testwatchdir";
watcher.NotifyFilter = NotifyFilters.FileName;
watcher.Filter = @"*.xml";
watcher.Created += new FileSystemEventHandler(watcher_Created);
watcher.EnableRaisingEvents = true;
 
J

Jeffrey Tan[MSFT]

Hi Allen,

Thank you for posting in the community!

Based on my understanding, you use the FileSystemWatcher class to monitor
all the xml files in certan directory. But you want to find a way to know
when a file's I/O is over.

=========================================
Let's use Notepad editing as an example.

For a file being editing, its content is loaded in the memory, so when user
use notepad to edit the xml file, it only changes the memory content of
this xml file, the file system knows nothing about this change. The file
system will be notified when you use save method to flush the memory
content to the disk.

If the notepad has saved the content, the file system will have not chance
to know the future behavior it will do with the xml file:
1). It may just close(I think this is what you means the change is over)
2). It may edit the content again, and save it to the disk.

At this point, you will see that, the change over control is not due to the
File System, but the file editor's process. So I think what you want does
not make much sense.

Also, we can not say that this can not be done in windows. Because you may
find all the file handle owners of the xml file. But the file handle owner
is being maintained in kernal mode, you must P/invoke some un-documented
APIs to get this done.(I think this is not what you want)

For a little start point of the un-documented API about this, please refer
to:
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&frame=right&th=d
392ffdb818c5665&seekm=vL7bp2axCHA.3256%40cpmsftngxa06#link1

========================================
Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.
Have a nice day!!

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
A

Allen Anderson

Hi Jeff, thanks for your reply.

In the example you stated, you are surely right that what happens in
memory can't be seen on disk, however this doesn't really matter in
what I need. I am trying to find a way to be notified when a file has
been created and closed. My current problem is that I'm being
notified just as the file starts writing to disk.

I can solve this problem by simply taking the notification, then
waiting till the file is no longer blocked, but I was hoping there was
a notification that did that already.

Cheers,
Allen
 
J

Jeffrey Tan[MSFT]

Hi Allen,

Thanks very much for your feedback.

I have understood what you want, also, I have seen your concern: You want
to be notified when the file creating is over(The user invoke CloseHandle
to close the file handle)

As I think, when the file handle is closed, the file system may only be
notified at kernal mode.(I will confirm my thought for you, and will update
you ASAP).

I think your solution of monitering the block state of the file may be a
suitable solution.

Anyway, I will consult this issue for you. Thanks for your understanding.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
A

Allen Anderson

thanks for checking into this for me. It just seems really strange to
me there wouldn't be any notification for a new file created/closed as
this seems pretty basic. Let me know what you find out.

thanks again
Allen
 
J

Jeffrey Tan[MSFT]

Hi Allen,

Sorry for letting you wait for so long time.

Based on your feedback, you only want to be notified when your file
creation is over.

=============================================
Althrough FileSystemWatcher class does not expose a closed event, but I
think you can just use Changed event to get you want.

After a process created a file and finished writing data into the new
created file, it will invoke CloseHandle to release the file handle. Also,
at this time, the file's lastwrite attribute will be modified, then the
FileSystemWatcher.Changed event will fire. So you can just use the Changed
event to determine the creating over of the file.

Like this:

private void button1_Click(object sender, System.EventArgs e)
{
StreamWriter sw = new StreamWriter(@"D:\TestFile.txt") ;
System.Threading.Thread.Sleep(5000);
for(int i=0;i<10000;i++)
{
// Add some text to the file.
sw.Write("This is the ");
sw.WriteLine("header for the file.");
sw.WriteLine("-------------------");
// Arbitrary objects can also be written to the file.
sw.Write("The date is: ");
sw.WriteLine(DateTime.Now);

}

sw.Close();
}

private void Form1_Load(object sender, System.EventArgs e)
{
FileSystemWatcher watcher = new FileSystemWatcher();

watcher.Path = @"D:\";
watcher.Filter = @"*.txt";
watcher.Created+=new FileSystemEventHandler(watcher_Created);
watcher.Changed+=new FileSystemEventHandler(watcher_Changed);
watcher.EnableRaisingEvents = true;
}

private void watcher_Created(object sender, FileSystemEventArgs e)
{
Console.WriteLine("watcher_Created");
}

private void watcher_Changed(object sender, FileSystemEventArgs e)
{
Console.WriteLine("watcher_Changed");
}

After some consulting and researching, I was told that .Net
FileSystemWatcher class actually encapsulate the Win32 API
ReadDirectoryChangesW(), there is a 1:1 relationship between them. So the
FileSystemWatcher class can only provide the function that
ReadDirectoryChangesW() expose.

=================================================
If you still have anything unclear, please feel free to tell me, I will
help you.


Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
G

Guest

Hi Allen,

Thanks for your feedback.

I am glad I can help you. If you have any further concern, please feel free
to tell me, I will help you.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top