我有一个项目使用 .net FileSystemWatcher 来观看 Samba 网络共享的视频文件。当它看到一个文件时,它会将它添加到一个编码队列中。当文件出队时,它们被移动到本地目录,然后该过程将文件编码为几种不同的格式并将它们吐出到输出目录。
问题的出现是因为视频文件太大,往往需要几分钟才能完全复制到网络目录中,所以当一个文件出列时,它可能已经或可能没有完全完成复制到网络分享。当从 Windows 机器复制文件时,我可以解决它,因为尝试移动仍在复制的文件会引发 IOException。我只是捕获异常并每隔几秒重试一次,直到完成复制。
但是,当文件从运行 OS X 的计算机放入 Samba 共享时,不会抛出 IOException。相反,部分文件被复制到工作目录,然后由于它不是有效的视频文件而无法编码。
所以我的问题是,有什么方法可以让 FileSystemWatcher 在触发其“已创建”事件之前等待文件完全写入(基于 this question 我认为该问题的答案是“否”)?或者,有没有办法让从 OS X 复制的文件的行为类似于 Windows 中的文件?或者我是否需要寻找另一种解决方案来观看 Samba 共享?感谢您的帮助。
最佳答案
选项 3。您最好的选择是有一个进程来监视文件的传入共享。当它看到一个文件时,记下它的大小和/或修改日期。
然后,过一段时间(比如 1 或 2 秒)后,再看一遍。记下之前看到的任何文件,并将它们的新尺寸/修改日期与您上次看到的文件进行比较。
任何在“足够长”的时间段(1 秒?5 秒?)内没有更改的文件都被视为“完成”。
一旦你有了一个“完成”的文件,将该文件移动/重命名到另一个目录。您的加载过程可以从这个目录运行。它“知道”此目录中只有完整的文件。
通过这两个阶段的过程,您以后可以添加其他规则来接受文件,因为所有这些规则都必须通过才能将文件移动到其适当的暂存区域(您可以检查格式,检查大小等)超出了文件存在的简单规则。
您以后的进程可以依赖文件的存在,作为启动机制和重启机制。当进程在失败或关闭后重新启动时,它可以假定第二阶段中的任何文件都是新的或不完整的,并根据其自身的内部状态采取适当的措施。处理完成后,它可以选择删除文件,或将其移动到“已完成”区域进行存档或其他操作。
关于c# - 为什么 OS X 在复制到 Samba 共享时不像 Windows 那样锁定文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9985034/