I have a task to save versions of documents for specified directory and look for changes.
before each change i need to keep the CURRENT version of the file in other place.
but the filesystemWatcher doesnt help me here because its events is after the change...
what should i do ?
You'd want to snapshot the target directories before watching them, like when your service starts up or something, that way when the file change comes through you have the base to compare to.
Related
I want to replicate all changes to a given folder. I use the FileSystemWatcher in C# and I can detect most changes. One type of change that I cannot detect easily is a move of a complete folder to the watched folder. I receive only a create-event for the folder but no events for the content of that moved folder. I can think of some logic to figure out if it is a move or just a creation of a new folder, but it seems awkward that it is quite hard to do this. Any suggestions in easy/out-of-the-box folder-move detection?
Thans a lot!
I receive only a create-event for the folder but no events for the content of that moved folder.
That's correct as OS does not "copy+delete" the folder internals. It's just "relink" the folder in the file system. As just a 'fast' idea - you cold check if 'created' folder is empty or not at the moment the create event received. If the folder is not empty you cold assume it was moved.
How I may know which file is modified and what data is changed in the file?
Edit: I want to watch the file as it gets modified and then compare it against a previous version to know which data blocks are changed. I guess watching the file for changes can be accomplished by using file watcher API but I have no idea about the second part.
You may need the FileSystemWatcher class.
The most common approach is define FileSystemWatcher, subscribe to its events and process them accordingly to the logic of your application.
Here is a simple example.
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!
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.
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).
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.
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...
File system watcher class in .net provides two methods:-
OnChanged
OnRenamed
You can set the EnableRaisingEvents to true and that is!!!! Every thing is simple with Dot Net chill!!!
Other than reading all the files and comparing them with a previous snapshot, is there a way to detect when a directory changes in C# with Windows? I don't mind PInvoke if that's what it takes.
EDIT The FileSystemWatcher class is great, but one gotcha is that you must kick off any work in the callback notification to a background task/thread to avoid blocking which will cause dropped events.
Use the FileSystemWatcher class - it does what you want. It won't tell you which bytes in the file changed, but it will tell you which files have changes.
From the doc:
Use FileSystemWatcher to watch for
changes in a specified directory. You
can watch for changes in files and
subdirectories of the specified
directory. You can create a component
to watch files on a local computer, a
network drive, or a remote computer.
To watch for changes in all files, set
the Filter property to an empty string
("") or use wildcards ("."). To
watch a specific file, set the Filter
property to the file name. For
example, to watch for changes in the
file MyDoc.txt, set the Filter
property to "MyDoc.txt". You can also
watch for changes in a certain type of
file. For example, to watch for
changes in text files, set the Filter
property to "*.txt".
There are several types of changes you
can watch for in a directory or file.
For example, you can watch for changes
in Attributes, the LastWrite date and
time, or the Size of files or
directories. This is done by setting
the NotifyFilter property to one of
the NotifyFilters values. For more
information on the type of changes you
can watch, see NotifyFilters.
You can watch for renaming, deletion,
or creation of files or directories.
For example, to watch for renaming of
text files, set the Filter property to
"*.txt" and call the WaitForChanged
method with a Renamed specified for
its parameter.
I've had to do this for a program that would watch a directory and see if any new image files were added, and it would then automatically resize them. When someone would add multiple files at one time, the watcher wouldn't catch all the files since it was single threaded and was busy resizing one image while another was being dropped.
I had to make this a multi-threaded app, where the main thread just watched the directory and added the files to a queue, and another thread would read from the queue and resize those images.
That's something you might want to be careful of if you're going to be doing anything with the files.
I am working on files n folder using C#....May I know is there any way to get the UID for file-folders....Till now i was using the full path of the file....But my problem in is renaming of files n folder...which will change the UID for file folder..
Plz is ther any way to do the same
thanks in advance
First, I think you can get clearer responses if you more clearly define what you mean by "working on files."
No, there's nothing like a "UID" for file or directories. But if you wish to dynamically monitor the state of files and directories, and have events raised notifying you when they are moved/changed/deleted, etc. You can use .NET's FileSystemWatcher class.
Using that technique you could start off, for example, with a Dictionary whose key might be some UID or GUID, or whatever, of the form Dictionary<UID,string>, where string might be the original filename. You could then, as you receive events from the FileSystemWatcher, update a second Dictionary<UID,string> where its string might be the changed file path :
I'm not really proposing you specifically use Dictionaries here, but just using them as possible examples of data structures you could create to keep track of certain files by original name/location and by (possibly) changed name/location ... or if they are deleted, copied, etc.
Hey.. there is a sample provided by microsoft.. it is installed in
"Windows Mobile 6 SDK\Samples\PocketPC\CPP\win32\FileChangeNotif"
location of your hard drive..
through filechangenotif smaple you will get the information about file change notification like
Renaming file,Deletion, addition...hope this can help you
Sorry, there's nothing you can reliably trace that's retained after a file/folder is moved or renamed. Your only real option is to keep track of the renames or simply tell the user that the file's not there anymore.