2

I'm trying to find the most reliable way of finding new and modified files in a directory using C# and .NET. I'm not looking for a real time solution, I want to check for changes at given times. It could be every 5 minutes or every hour etc.

We have CreationTime and LastWriteTime on the FileInfo object, and this seems to be enough to get new and modified files. But if a file is renamed none of the available dates are changed and the file will be missed if we just look at CreationTime and LastWriteTime.

At the moment i'm maintaining af "snapshot" of the files in the directory including the time of the last check for changes. This enables me to compare all the files in the directory with files in the snapshot, if the snapshot is missing a file it is either new or renamed.

Is this the only way? Rr am I missing something. I'm not going to use FileSystemWatcher as it seems pretty "buggy" and is required to run all the time.

Any suggestions are very welcome.

Merry Christmas!

TheBoyan
  • 6,802
  • 3
  • 45
  • 61
Christian Sparre
  • 955
  • 3
  • 15
  • 25

5 Answers5

6

Use the FileSystemWatcher class, it's the good way. Maybe you could be more specific with the

as it seems pretty "buggy"

EDIT: FileSystemWatcher does support renaming events.

ken2k
  • 48,145
  • 10
  • 116
  • 176
  • 2
    The OP has specifically mentioned that he doesn't need realtime and doesn't want to use the FileSystemWatcher class. However, if you think he should then you need to explain **why** it will solve the problem. – ChrisF Dec 23 '11 at 13:06
  • 4
    The FileSystemWatcher is not running all the time, Christian. It is waiting for events. When the FileSystemWatcher is started, it asks the Windows OS to be informed about file events on specified files or directories. When file operations occur, Windows checks the file pattern you specified and if there is a match a FileSystemWatcher event is raised. – Olivier Jacot-Descombes Dec 23 '11 at 13:45
  • 2
    This is the **right** way to do it. The comment about it being *buggy* probably stems from inexperience with the class. – Yuck Dec 23 '11 at 13:52
  • The FileSystemWatcher may seem "buggy" in certain circumstances. I used it to communicate between to applications. One Application wrote information into a file. The other read the file and deleted it. The problem was that the file creation event happened before the first Application had finished writing into the file. The solution was to listen to the "rename" event instead. The First Application wrote to a file with a temporary name and when finished, renamed the file to its definitive name. – Olivier Jacot-Descombes Dec 23 '11 at 13:54
1

The Microsoft Sync Framework has components for synchronising files.

The framework covers all data types and data storage and the file system component should be more reliable than the FileSystemWatcher. As it says in the MSDN:

It can be used to synchronize files and folders in NTFS, FAT, or SMB file systems. The directories to synchronize can be local or remote; they do not have to be of the same file system. An application can use static filters to exclude or include files either by listing them explicitly or by using wildcard characters (such as *.txt). Or the application can set filters that exclude whole subfolders. An application can also register to receive notification of file synchronization progress

I know you really only want to know when files have changed, but given that you've already dismissed the FileSystemWatcher route it might be the only reliable route (other than doing what you are in maintaining a snapshot yourself).

ChrisF
  • 134,786
  • 31
  • 255
  • 325
  • Thank you Chris, I did consider the Sync Framework, however if I'm not mistaken it needs to be a pair of folders, right? I'm just looking for a way to detect changes. Is this possible using the Sync Framework? – Christian Sparre Dec 23 '11 at 13:09
  • @ChristianSparre - Hmm, not sure. I must admit I've only used it for synchronising databases where there is the need to have two copies. – ChrisF Dec 23 '11 at 13:11
  • This seems to be about synchronizing files (__propagating__ changes), not about __tracking *when* changes were made__. – Adam Dec 23 '11 at 13:11
  • @codesparkle - I know, but it might be the only reliable way to go if the `FileSystemWatcher` route can't cope. – ChrisF Dec 23 '11 at 13:15
  • Well the "FileSyncProvider" from the Sync Framework is able to detect the files, however it needs somewhere to "put" the changes or else it will just repeat detecting the same files. I will try to see if it is possible to create a "dummy" provider :) – Christian Sparre Dec 23 '11 at 13:27
1

Your problem looks very much like a Database with no primary key.

If you asssign, say, a GUID to each file in that folder and check for that GUID instead of the filename, your application will be much more reliable.

So that's the theory, in practice, we're talking metadata. Depending on your system, and the files contained in that folder, you could use Alternate Data Streams.

Here is a SO question about it.

It boils down to having information on a file that is not stored within the file, it is merely linked to it.
You can then look it up in a DOS box:

notepade.exe myfile.txt:MYGUID

It requires the system to use NTFS.

HTH.

Community
  • 1
  • 1
Louis Kottmann
  • 16,268
  • 4
  • 64
  • 88
0

File system watcher class in .net provides two methods:-

  1. OnChanged
  2. OnRenamed

You can set the EnableRaisingEvents to true and that is!!!! Every thing is simple with Dot Net chill!!!

SANDIP
  • 89
  • 1
  • 4
0

A very primitive approach would use a command of "dir" and comparing outputs...

Here is some info on params: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/dir.mspx?mfr=true

Along with you snapshot of dates, you can compare the outputs of dir... its very fast and low on resources consuming...

Ironicnet
  • 547
  • 3
  • 14