Click here to Skip to main content
15,125,074 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi guys,

I am trying to monitor a chunky txt file that is open by another app at all times. As far as I can tell app is holding file open and appends some stuff into it. It's all cool I can still access the file and all I need is read only, so far so good.

I have set up a FileSystemWatcher to keep an eye on my file but sadly no events gets triggered no matter what filters I have set. Now before you run me down through the basics, keep in mind I tested it manually with different filters and it's all working just fine as long as it's me who makes modifications (via notepad, notepad++, word etc..).

I am not looking for code to solve my problem, I am looking for an explanation. I have been off coding in .net for a while and maybe something changed that I am not aware of? To me it looks like in my case windows is not reporting changes to the file most likely because some 3rd party app has its mits on it.

I dont really have to use FileSystemWatcher I can see a number of work arounds but I like to use things that were designed for the purpose... Any advice/guidance will be more than welcome.

AD1 = Might be worth mentioning that I can even see, size of the file changing yet file watcher does not give a... I can even compare file size every 10s to get better results than FileSystemWatcher provides. Simply it seems to be oblivious to any changes as long as these are made by 3rd party app.

AD2 = Giving it some thought and couple more tests it looks like Windows does not report changes to locked files, read in shared mode. Until files is closed windows reports no changes until you highlight mentioned file in windows explorer, somehow that forces bash to report changes but you cant call that a solution. All this makes little sense especially that I can see windows keep updating file size info almost every couple seconds.

AD3 = Trying similar approach with C++ and ReadDirectoryChanges brings similar results.

Please let me know if I can provide any more info.

What I have tried:

Pretty much everything including exhausting google research.
Posted
Updated 27-Mar-21 13:46pm
v5
Comments
Dave Kreskowiak 26-Mar-21 22:24pm
   
What Notify Filters do you have set in your FSW instance? Without seeing the code that sets up the FSW, it's not really possible to tell you what's going on.
Wajrak_ 27-Mar-21 0:59am
   
Last time I tried with all the filters that came to my mind so last version was this:

watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.CreationTime | NotifyFilters.LastAccess | NotifyFilters.DirectoryName;

watcher.Filter = "*.*";

Allthough I only need lastwrite or lastaccess. Again, code works fine as long as change to the file is made by certain apps. I dont mind sharing code I simply dont have it anymore, I've tried 5 different approaches to no avail and moved on, I would like to know why this is happening though. I also tried increasing buffer sizes to pretty much maximum, shifting FSW to top of hierarchy, kept it away form loops and built test solution just to figure it out... to no avail.

Quote:
The Changed event is raised when changes are made to the size, system attributes, last write time, last access time, or security permissions of a file or directory in the directory being monitored.
(FileSystemWatcher.Changed Event (System.IO) | Microsoft Docs[^])
So files which are opened for writing (or read / write) will not be detected as changed until the file is actually closed (or possibly flushed, though that is less likely)
Try it yourself:
Set up a timer that displays the data:
C#
FileInfo fi = new FileInfo(@"D:\Test Data\AAA.txt");
txtFileInfo.Text = $"{fi.LastAccessTime}|{fi.LastWriteTime}|{fi.CreationTime}";
Then three buttons:
C#
private FileStream fs = null;
 private void butOpen_Click(object sender, EventArgs e)
     {
     fs = new FileStream(@"D:\Test Data\AAA.txt", FileMode.Open, FileAccess.ReadWrite);
     }

 private void butClose_Click(object sender, EventArgs e)
     {
     if (fs != null)
         {
         fs.Close();
         fs = null;
         }
     }

 private void butChange_Click(object sender, EventArgs e)
     {
     if (fs != null)
         {
         byte[] data = System.Text.Encoding.UTF8.GetBytes(DateTime.Now.ToLongTimeString());
         fs.Write(data, 0, data.Length);
         }
     }
The access info isn't altered until the stream is closed - which makes sense, because that's the only point at which the system can be sure that the file data is internally consistent rather than being "half way changed".
   
Comments
Dave Kreskowiak 27-Mar-21 18:42pm
   
will not be detected as changed until the file is actually closed (or possibly flushed, though that is less likely)
AND not until the file system updates the last modified datetime, which may not happen until much later than the file operation.
You're making assumptions as to how the FSW works and what it can detect.

If an application saves its data to a temporary file, then deletes the original file and renames the temp file, THIS WILL NOT BE DETECTED BY FSW. Why? Because the FSW takes snapshots of whatever is being monitored, like a folder.

Visual Studio and Office applications are notorious for doing this. On one snap shot, there is a list of files with certain datetimes on them, like Created, Last Modified, ... An application makes its changes, like Office does, and the next snapshot occurs and the file list and metadata compared to the last snapshot. According to FSW, nothing changed, even though the original file is gone and a temp file is taking its place with the same filename.
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900