如何可靠地检查当前正在写入的文件是否已在.net中完成?

时间:2015-10-27 11:04:44

标签: c# .net

我对此进行了大量搜索,并发现了很多关于此主题的其他问题,可以归结为使用FileSystemWatcher,并在其Changed事件中打开文件以便使用{{ 1}}并检查是否抛出异常。但是,这对我来说只有一半的时间。

我创建了一个简单的控制台应用程序来测试这种行为,它基本上归结为以下几点:

FileShare.None

我现在用不同的文件和目录测试了这个,这是我的结果:

小文件(1MiB)

通过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

正确的结果。

1GiB大文件

通过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

也是正确的结果

大文件(10GiB)

通过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

正确的结果。

那么,如果写入监视目录的文件真的“完整”,即“可用”,我应该怎样接近可靠的检测?

我目前的做法如下:

  1. 倾听d:\locktest\10g created d:\locktest\10g changed d:\locktest\10g complete Created
  2. 尝试在那里打开文件
  3. 如果打开文件失败,请将此文件作为“候选”放入要再次检查的(同步)文件列表中
  4. 每隔X秒检查此列表
  5. 如果列表中的某个文件出现Complete,请将其从中删除并立即检查,再次失败时重新添加
  6. 这涉及某种民意调查,对我来说看起来有些“狡猾”。另外,对于非常小的文件,我得到两次完整的信息,所以我想我必须跟踪已经完整的文件并检查它们是否已经改变。

    这是唯一的方法吗?还是有更好的方法?

0 个答案:

没有答案
相关问题