我对此进行了大量搜索,并发现了很多关于此主题的其他问题,可以归结为使用FileSystemWatcher
,并在其Changed
事件中打开文件以便使用{{ 1}}并检查是否抛出异常。但是,这对我来说只有一半的时间。
我创建了一个简单的控制台应用程序来测试这种行为,它基本上归结为以下几点:
FileShare.None
我现在用不同的文件和目录测试了这个,这是我的结果:
通过Windows资源管理器复制
FileSystemWatcher fsw = new FileSystemWatcher("d:\\locktest");
fsw.Changed += (sender, e) => {
String fp = e.FullPath;
Console.WriteLine(fp + " changed");
try {
using(FileStream s = new FileStream(fp, FileMode.Open, FileAccess.Read, FileShare.None)) { }
Console.WriteLine(fp + " complete");
} catch (IOException ex) {
Console.WriteLine(fp + " not complete");
}
};
fsw.Created += (sender, e) => Console.WriteLine(e.FullPath + " created");
fsw.EnableRaisingEvents = true;
Console.ReadKey(); // would immediately exit otherwise
结果:正确,但两次。
通过DOS d:\locktest\1mb created
d:\locktest\1mb changed
d:\locktest\1mb complete
d:\locktest\1mb changed
d:\locktest\1mb complete
与Windows资源管理器相同。
通过Cygwin copy
cp
正确的结果。
通过Windows资源管理器复制
d:\locktest\1mb created
d:\locktest\1mb changed
d:\locktest\1mb complete
正确的结果。
通过DOS d:\locktest\1g created
d:\locktest\1g changed
d:\locktest\1g not complete
d:\locktest\1g changed
d:\locktest\1g complete
相同的结果
通过Cygwin copy
cp
也是正确的结果
通过Windows资源管理器复制
d:\locktest\1g created
d:\locktest\1g changed
d:\locktest\1g complete
最后一次“更改”事件被“过早”或更好地触发:文件完成时未触发“已更改”事件
通过DOS d:\locktest\10g created
d:\locktest\10g changed
d:\locktest\10g not complete
d:\locktest\10g changed
d:\locktest\10g not complete
相同的结果
通过Cygwin copy
cp
正确的结果。
那么,如果写入监视目录的文件真的“完整”,即“可用”,我应该怎样接近可靠的检测?
我目前的做法如下:
d:\locktest\10g created
d:\locktest\10g changed
d:\locktest\10g complete
和Created
Complete
,请将其从中删除并立即检查,再次失败时重新添加这涉及某种民意调查,对我来说看起来有些“狡猾”。另外,对于非常小的文件,我得到两次完整的信息,所以我想我必须跟踪已经完整的文件并检查它们是否已经改变。
这是唯一的方法吗?还是有更好的方法?