我正在编写一个应用程序,它通过每隔几秒轮询一次目录来监视新输入文件的目录。新文件通常可能是几兆字节,因此需要一些时间才能完全到达输入目录(例如:从远程共享复制)。
是否有一种简单的方法可以检测文件当前是否正在被复制?理想情况下,任何方法都是平台和文件系统无关的,但是不同平台可能需要特定的策略。
我已经考虑将两个目录列表分隔几秒钟并比较文件大小,但这引入了时间/可靠性权衡,除非没有其他选择,否则我的上司不满意。
对于后台,该应用程序是作为一组Matlab M文件编写的,所以没有JRE / CLR技巧我害怕......
编辑:文件通过直接移动/复制操作直接到达输入,无论是从网络驱动器还是从本地文件系统上的其他位置。此复制操作可能由人类用户而不是其他应用程序启动。
因此,在文件提供程序上添加控制文件或使用中间暂存区域是非常困难的......
结论:似乎没有简单的方法可以做到这一点,所以我已经决定采用腰带和括号的方法 - 如果出现以下情况,文件就可以处理:
感谢大家的回复!
答案 0 :(得分:7)
最安全的方法是让将文件放在目录中的应用程序首先将它们放在不同的临时目录中,然后将它们移动到真实的目录(即使使用FTP或者也应该是原子操作)文件共享)。您还可以使用命名约定在一个目录中实现相同的结果。
修改强> 它真的取决于文件系统,它的复制功能是否具有“已完成文件”的概念。我不太了解SMB协议,但如果它有这个概念,你可以编写一个暴露SMB接口(或补丁Samba)的应用程序和一个API,以获得完整文件副本的通知。可能还有很多工作要做。
答案 1 :(得分:3)
这是一个像山丘一样古老的中间件问题,简短的回答是:没有。
这两个'解决方案'将责任放在文件上传器上:(1)将文件上传到临时目录,然后将其移动到目标目录(2)上传文件,然后创建/上传'准备就绪'表示内容文件状态的文件。
第一个更好,但两者都不优雅。事实是,存在比文件系统更好的通信媒体。考虑使用一些仅涉及推送或拉取的IPC(而不是文件系统中的两者),例如HTTP POST,JMS或MSMQ队列等。此外,这也可以是同步的,允许进程接收文件承认内容,甚至检查它的价值,并交给客户一张收据 - 这是通往不可否认的正义道路。遵循这一点,您永远不会对文件是否已经交付到您的服务器进行处理进行争论。
微米。
答案 2 :(得分:1)
一种简单的可能性是以相当大的间隔(2到5分钟)进行轮询,并且只在第二次看到它时才会确认新文件。
我不知道在任何操作系统中确定文件是否仍在被复制的方式,除了可能检查文件是否被锁定。
答案 3 :(得分:1)
文件如何到达那里?你可以在写入时设置属性,然后在写入完成后更改属性吗?这需要通过写作的东西来完成......听起来这不是一个选择。
否则,如果文件具有两个连续列表的相同文件大小,则缓存列表并将文件视为新文件是我能想到的最佳方式。
或者,您可以在文件上使用修改时间 - 文件必须是新的,并且修改时间至少为过去的x。但我认为这相当于缓存列表。
你每隔几秒就查看一次这个文件夹,它的惩罚时间不是很多吗?它的平台不可知。
另外,仅限linux:http://www.linux.com/feature/144666
与cron相似但是对于文件。不知道它如何处理您的具体问题 - 但可能有用吗?
答案 4 :(得分:0)
你的操作系统是什么?在unix中,您可以使用“lsof”实用程序来确定用户是否打开了要写入的文件。显然,MS Windows Process Explorer中的某个地方有相同的功能。
另外,您可以尝试对文件进行独占打开,然后保释失败。但这可能有点不可靠,很容易踩到你自己的脚趾。