C# 如何判断文件是否被修改?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13014704/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to work out if a file has been modified?
提问by Dave
I'm writing a back up solution (of sorts). Simply it copies a file from location C:\ and pastes it to location Z:\
我正在编写一个备份解决方案(各种)。只需从位置 C:\ 复制文件并将其粘贴到位置 Z:\
To ensure the speed is fast, before copying and pasting it checks to see if the original file exists. If it does, it performs a few 'calculations' to work out if the copy should continue or if the backup file is up to date. It is these calculations I'm finding difficult.
为保证速度快,复制粘贴前先检查原文件是否存在。如果是,它会执行一些“计算”来确定副本是否应该继续或备份文件是否是最新的。我发现这些计算很困难。
Originally, I compared the file size but this is not good enough because it would be very possible to change a file and it to be the same size (for example saving the character C in notepad is the same size as if I saved the Character T).
最初,我比较了文件大小,但这还不够好,因为很可能将文件更改为相同的大小(例如,在记事本中保存字符 C 的大小与保存字符 T 的大小相同)。
So, I need to find out if the modified date differs. At the moment, I get the file info using the FileInfoclass but after reviewing all the fields there is nothing which appears to be suitable.
所以,我需要找出修改日期是否不同。目前,我使用FileInfo该类获取文件信息,但在查看所有字段后,似乎没有任何合适的内容。
How can I check to ensure that I'm copying files which have been modified?
如何检查以确保我正在复制已修改的文件?
EDITI have seen suggestions on SO to use MD5 checksums, but I'm concerned this may be a problem as some of the files I'm comparing will be up to 10GB
编辑我已经看到关于使用 MD5 校验和的建议,但我担心这可能是一个问题,因为我比较的一些文件将高达 10GB
采纳答案by Mike Marynowski
Going by modified date will be unreliable - the computer clock can go backwards when it synchronizes, or when manually adjusted. Some programs might not behave well when modifying or copying files in terms of managing the modified date.
按照修改日期进行操作是不可靠的 - 计算机时钟在同步或手动调整时可能会倒退。就管理修改日期而言,某些程序在修改或复制文件时可能表现不佳。
Going by the archive bit might work in a controlled environment but what happens if another piece of software is running that uses the archive bit as well?
通过存档位可能在受控环境中工作,但是如果另一个软件也在运行,并且使用存档位会发生什么?
The Windows archive bit is evil and must be stopped
If you want (almost) complete reliability then what you should do is store a hash value of the last backed up version using a good hashing function like SHA1, and if the hash value changes then you upload the new copy.
如果你想要(几乎)完全的可靠性,那么你应该做的是使用一个好的散列函数(如 SHA1)存储最后一个备份版本的散列值,如果散列值发生变化,则上传新副本。
Here is the SHA1 class along with a code sample on the bottom:
这是 SHA1 类以及底部的代码示例:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha1.aspx
http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha1.aspx
Just run the file bytes through it and store the hash value. Pass a FileStreamto it instead of loading your file into memory with a byte array to reduce memory usage, especially for large files.
只需通过它运行文件字节并存储哈希值。将 a 传递FileStream给它而不是使用字节数组将文件加载到内存中以减少内存使用量,尤其是对于大文件。
You can combine this with modified date in various ways to tweak your program as needed for speed and reliability. For example, you can check modified dates for most backups and periodically run a hash checker that runs while the system is idle to make sure nothing got missed. Sometimes the modified date will change but the file contents are still the same (i.e. got overwritten with the same data), in which case you can avoid resending the whole file after you recompute the hash and realize it is still the same.
您可以将其与修改日期以各种方式结合起来,以根据速度和可靠性的需要调整您的程序。例如,您可以检查大多数备份的修改日期,并定期运行在系统空闲时运行的哈希检查器,以确保没有遗漏任何内容。有时修改日期会改变但文件内容仍然相同(即被相同的数据覆盖),在这种情况下,您可以避免在重新计算散列并意识到它仍然相同后重新发送整个文件。
Most version control systems use some kind of combined approach with hashes and modified dates.
大多数版本控制系统使用某种带有哈希和修改日期的组合方法。
Your approach will generally involve some kind of risk management with a compromise between performance and reliability if you don't want to do a full backup and send all the data over each time. It's important to do "full backups" once in a while for this reason.
如果您不想进行完整备份并每次都发送所有数据,您的方法通常会涉及某种风险管理,并在性能和可靠性之间做出妥协。出于这个原因,偶尔做一次“完整备份”很重要。
回答by dsgriffin
You may like to check out the FileSystemWatcherclass.
您可能想查看FileSystemWatcher类。
"This class lets you monitor a directory for changes and will fire an event when something is modified."
“这个类让你监控目录的变化,并在修改某些内容时触发一个事件。”
Your code can then handle the event and process the file.
然后您的代码可以处理事件并处理文件。
Code source - MSDN:
代码源 - MSDN:
// Create a new FileSystemWatcher and set its properties.
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = args[1];
/* Watch for changes in LastAccess and LastWrite times, and
the renaming of files or directories. */
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
// Only watch text files.
watcher.Filter = "*.txt";
// Add event handlers.
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
回答by Sergey Berezovskiy
You can compare files by their hashes:
您可以通过哈希比较文件:
private byte[] GetFileHash(string fileName)
{
HashAlgorithm sha1 = HashAlgorithm.Create();
using(FileStream stream = new FileStream(fileName,FileMode.Open,FileAccess.Read))
return sha1.ComputeHash(stream);
}
If content was changed, hashes will be different.
如果内容被更改,哈希值会有所不同。
回答by Robbie Dee
Generally speaking, you'd let the OS take care of tracking whether a file has changed or not.
一般来说,您会让操作系统负责跟踪文件是否已更改。
If you use:
如果您使用:
File.GetAttributes
And check for the archive flag, this will tell you if the file has changed since it was last archived. I believe XCOPY and similar reset this flag once it has done the copy, but you may need to take care of this yourself.
并检查存档标志,这将告诉您文件自上次存档以来是否已更改。我相信 XCOPY 和类似的东西一旦完成复制就会重置这个标志,但你可能需要自己处理这个。
You can easily test the flag in DOS using:
您可以使用以下命令轻松地在 DOS 中测试该标志:
dir /aa yourfilename
Or just add the attributes column in windows explorer.
或者只是在 Windows 资源管理器中添加属性列。
回答by Polyfun
The file archive flag is normally used by backup programs to check whether a file needs backing up. When Windows modifies or creates a file, it sets the archive flag (see here). Check whether the archive flag is set to decide whether the file needs backing up:
备份程序通常使用文件存档标志来检查文件是否需要备份。当 Windows 修改或创建文件时,它会设置存档标志(请参阅此处)。检查是否设置了归档标志来决定文件是否需要备份:
if ((File.GetAttributes(fileName) & FileAttributes.Archive) == FileAttributes.Archive)
{
// Archive file.
}
After backing up the file, clear the archive flag:
备份文件后,清除存档标志:
File.SetAttributes(fileName, File.GetAttributes(fileName) & ~FileAttributes.Archive);
This assumes no other programs (e.g., system backup software) are clearing the archive flag.
这假设没有其他程序(例如,系统备份软件)正在清除存档标志。

