0

我正在实现一个事件处理程序,它必须打开和处理由我无法控制的第三方应用程序创建的文件的内容。“C# 4.0 in a nutshell”(第 495 页)中的一条注释警告我,在文件完全填充之前打开文件的风险;所以我想知道如何处理这种情况。为了将事件处理程序的负载保持在最低限度,我正在考虑让处理程序简单地将文件名插入队列中,然后使用不同的线程来管理处理,但是,无论如何,我如何确保写入完成并且文件读取是安全的?文件大小可以是任意的。

有什么想法?谢谢

4

3 回答 3

1

我们的解决方法是观察特定的扩展。上传文件时,扩展名为“.tmp”。完成上传后,它被重命名为具有适当的扩展名。

另一种选择是让服务器尝试在 try/catch 块中移动文件。如果文件没有上传完成,移动文件的尝试会抛出异常,所以我们等待并重试。

于 2012-09-25T12:27:57.723 回答
1

实现您想要的可靠方法可能是使用 FileSystemWatcher + NTFS USN 日志。可能比您预期的要复杂,但仅 FileSystemWatcher 并不能确定新创建的文件已关闭

-首先是 FileSystemWatcher,用于了解文件的创建时间。从那里您可以获得完整的文件路径,并且距离获取文件唯一 ID 仅 1 或 2 个 pinvokes (这可以帮助您在其整个生命周期内跟踪它)。

- 然后,阅读 USN 日志,它会跟踪您驱动器上发生的所有事情。过滤与您的新文件 ID 对应的条目,并阅读日志,直到到达带有“关闭”事件的条目。

从那里开始,除非您的文件以特殊方式操作(由生成它的应用程序多次打开和关闭),否则您可以假设读取它并执行您想做的任何事情是安全的。

一个非常棒的 USN 日志解析器的 C# 实现是 StCroixSkipper 的工作,可在此处获得:http: //mftscanner.codeplex.com/

如果您有兴趣,我可以为您提供有关 USN 期刊的更多帮助,因为我在我的项目中使用它。

于 2012-09-25T13:33:10.227 回答
0

实际上,你无法知道。如果其他应用程序的“写”操作是打开文件而拒绝其他人的写访问,那么当它完成后,关闭文件。当您收到通知时,您只需打开请求写入权限的文件,如果失败,您就知道操作未完成。但是,如果“写”操作是打开文件、写入、关闭文件、再次打开文件、再次写入等等,那么你就很不走运了。

我见过的最好的解决方案是在最后一次通知之后设置一个计时器。当计时器结束时,尝试打开文件进行写入——如果可以的话,假设“操作”已经完成并做你需要做的事情。如果打开失败,假设操作仍在进行中并等待一段时间。

当然,没有什么是万无一失的。尽管如此,当您对文件执行您想要的操作并导致交互问题时,可能会启动另一个操作。

于 2012-09-25T13:12:22.983 回答