2012-09-25 43 views
0

我正在实现一个事件处理程序,它必须打开并处理由我无法控制的第三方应用程序创建的文件的内容。我在“C#4.0简而言之”一书(第495页)中提到有关在文件完全填充之前打开文件的风险的警告;所以我想知道如何管理这个事件。为了尽量减少事件处理程序的负载,我正在考虑让处理程序简单地在队列中插入文件名,然后使用不同的线程来管理处理,但是,无论如何,我如何确保写入完成并且读取的文件是安全的?文件大小可以是任意的。FileSystemWatcher和写入完成

有些想法?谢谢

回答

1

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

-first,FileSystemWatcher,知道何时创建文件。从那里你有完整的文件路径,并获得1或2 pinvokes获取文件的唯一ID(它可以帮助你跟踪它在整个生命周期)。

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

从那里,除非你的文件被特殊的方式操作(由生成它的应用程序多次打开和关闭),否则你可以认为阅读它是安全的,并且做你想做的任何事情。

一个真正伟大的USN日志分析器的C#实现是StCroixSkipper的工作,请访问: http://mftscanner.codeplex.com/

如果你有兴趣,我可以给你USN日记更多的帮助,正如我在项目中使用它。

+0

事实上,一个更脏或更便宜/更简单的方法来实现或多或少相同的事情将是做什么建议在[这个SO链接问题](http://stackoverflow.com/questions/12588605/is-file-being - 现在右键 - 现在#comment16964757_12588605) – mbarthelemy

+0

merci bien pur ton助手,c'esttrésinteressant。 Bien sur j'irai te demender de l'aide si j'aurai besoin de comprendre quelque choose de plus。 – Daniel

1

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

另一种方法是让服务器尝试在try/catch块中移动文件。如果未完成上传,则移动文件的尝试将引发异常,所以我们等待并重试。

+0

我忘了指定:程序不是客户端服务器,它可以在桌面上运行,所以我猜想没有任何提示可以工作......或者我错了吗? – Daniel

+0

两者都可以在桌面应用中使用。问题是相同的,并且解决方法是相同的。 – David

0

实际上,你无法知道。如果其他应用程序的“写入”操作是打开拒绝其他人写入访问的文件,则在完成时关闭文件。当您收到通知时,您可以简单地打开请求写入访问的文件,如果失败,您知道操作未完成。但是,如果“写入”操作是打开文件,写入,关闭文件,再次打开文件,再次写入等,那么你几乎不走运。

我见过的最佳解决方案是在上次通知后设置一个计时器。当计时器过去时,尝试打开文件进行写入 - 如果可以的话,假设“操作”已完成,并执行您需要执行的操作。如果打开失败,则假定操作仍在进行中并等待更多。

当然,没有什么是万无一失的。尽管如此,另一项操作可能会在您按照自己想要的文件操作时开始,并导致交互问题。