【发布时间】:2015-03-26 15:55:25
【问题描述】:
我熟悉 FileSystemWatcher 类,并且已经使用它进行了测试,或者我已经使用快速循环进行了测试,并在目录中列出了类型文件的目录列表。在这种特殊情况下,它们是 zip 压缩的 SDF 文件,我需要解压缩、打开和查询。
问题是当一个大文件被放到一个目录中时,有时会花费一些时间,比如它被下载,或者从网络位置复制等等......
当 FileSystemWatcher 引发 OnChange 事件时,我有一个 ChangeType 句柄,并且在这些类型的操作中,创建是立即的,而文件仍未完全复制到该位置。
同样使用循环,我看到一个文件在整个文件之前。
FileSystemWatcher 引发了几个更改事件,一个在创建之后,然后一个或多个在复制期间,没有任何说明 这个文件现在已经完成
因此,如果我期望某种类型的文件最终被放置在一个目录中以进行读取和处理,而不知道它们的传输机制,也不知道它们的最终大小......
除了使用错误控制作为工作流控制之外,我如何知道文件何时准备好实际处理(尽管错误控制本来就应该存在)?这似乎是一种处理这个问题的坏方法,因为有时错误控制实际上可能代表一个合法问题,有时可能只是文件没有完全写入,我看不到任何真正安全的区分方法.
我鄙视预期的错误,但意识到它就像套接字一样有它的位置,没有什么能保证在尝试读/写之前对打开的检查不会改变。但我确实不惜一切代价避免它。
这个特别的问题主要是因为将要产生的信息模棱两可。对于由于没有完全遇到或以其他方式损坏而合法错误的文件有一个冲突队列,我不希望其他好的文件去那里。几乎不可能更细致地检测这种特定情况。
编辑: 我知道我可以做到这一点......而且我已经阅读了其他关于其他人做同样事情的 SA 文章。 (而且我知道这种方法既粗暴又阻塞,这只是一个例子。)
private static void OnChanged(object source, FileSystemEventArgs e)
{
if (e.ChangeType == WatcherChangeTypes.Created)
{
bool ready = false;
while (!ready)
{
try
{
using (FileStream fs = new FileStream(e.FullPath, FileMode.Open))
{
Console.WriteLine(String.Format("{0} - {1}", e.FullPath, fs.Length));
}
ready = true;
}
catch (IOException)
{
ready = false;
}
}
}
}
我试图找出这绝对是唯一的方法,是否没有其他组件,或者文件系统的某些挂钩可以通过适当的事件实际执行此操作?
【问题讨论】:
-
你可以做 pstools 句柄所做的 - 看看是否有人打开了文件(注意:我不知道句柄是如何工作的)。你当然可以使用句柄本身
-
我已经考虑过一个循环,它只会用打开的请求来填充文件,直到它不再抛出 IO 异常,然后认为它至少不再被使用。句柄的问题是我不知道 expect 可能有打开的句柄,有些不会干扰我需要做的事情。 Exempli gratia,一个 AV 产品或索引器可能正在扫描它,但我仍然可以按预期使用它。因此,handles 只告诉我是否有其他东西在看它,而不是它是否为我准备好了。
-
是的,在开始发布之前,我已经阅读了该文章和其他几篇 SA 文章,例如该主题有很多建议,但没有明确的示例答案,我选择更清楚地说明我的具体问题,而不是比坟墓挖那个。同样,我可能没有独占访问权限,因此我不能将其作为解决方案。我只需要可用的访问权限。
-
我想您可以使用 LastWrite 通知过滤器并进行日期比较。如果正在写入文件,则 LastWrite 应保持递增。
标签: c# file-io filesystemwatcher