2

我正在编写一个应用程序,通过每隔几秒钟轮询一次目录来监视新输入文件的目录。新文件通常可能有几兆字节,因此需要一些时间才能完全到达输入目录(例如:从远程共享复制)。

有没有一种简单的方法来检测文件当前是否正在被复制?理想情况下,任何方法都与平台和文件系统无关,但不同平台可能需要特定策略。

我已经考虑过将两个目录列表分开几秒钟并比较文件大小,但这引入了时间/可靠性权衡,除非别无选择,否则我的上级并不满意。

作为背景,该应用程序被编写为一组 Matlab M 文件,所以恐怕没有 JRE/CLR 技巧......


编辑:文件通过直接移动/复制操作直接到达输入,无论是从网络驱动器还是从本地文件系统上的另一个位置。此复制操作可能由人类用户而不是其他应用程序启动。

因此,很难让文件提供者负责添加控制文件或使用中间暂存区......


结论:似乎没有简单的方法可以做到这一点,所以我已经决定采用带大括号的方法 - 如果满足以下条件,则文件已准备好进行处理:

  • 它的大小在一定时间内不会改变,并且
  • 可以以只读模式打开文件(某些复制过程会锁定文件)。

感谢大家的回复!

4

5 回答 5

7

最安全的方法是让将文件放在目录中的应用程序首先将它们放在不同的临时目录中,然后将它们移动到真实目录(即使使用 FTP 或文件共享也应该是原子操作) . 您还可以使用命名约定在一个目录中实现相同的结果。

编辑: 这实际上取决于文件系统,取决于它的复制功能是否甚至具有“已完成文件”的概念。我不太了解 SMB 协议,但如果它有这个概念,您可以编写一个公开 SMB 接口(或修补 Samba)的应用程序和一个 API,以便在完成文件副本时获得通知。不过可能工作量很大。

于 2008-12-05T10:21:43.010 回答
3

这是一个由来已久的中间件问题,简短的回答是:不。

这两个“解决方案”将责任放在文件上传器上:(1)将文件上传到暂存目录中,然后将其移动到目标目录(2)上传文件,然后创建/上传一个“就绪”文件指示内容文件的状态。

第一个更好,但两者都不优雅。事实上,存在比文件系统更好的通信媒体。考虑使用一些只涉及推送或拉取的 IPC(而不是两者,文件系统也是如此),例如 HTTP POST、JMS 或 MSMQ 队列等。此外,这也可以是同步的,允许进程接收文件承认内容,甚至检查其价值,并给客户一张收据 - 这是不可否认的正义之路。遵循这一点,您将永远不会因文件是否已交付给您的服务器进行处理而争论不休。

M。

于 2008-12-05T10:32:45.483 回答
1

一种简单的可能性是以相当大的间隔(2 到 5 分钟)进行轮询,并且仅在您第二次看到新文件时才确认它。

除了检查文件是否被锁定之外,我不知道在任何操作系统中确定文件是否仍在被复制的方法。

于 2008-12-05T10:21:46.847 回答
1

文件是如何到达那里的?您可以在写入时为其设置属性,然后在写入完成时更改属性吗?这需要通过写作来完成……听起来这不是一个选择。

否则,缓存列表并将文件视为新文件(如果两个连续列表的文件大小相同)是我能想到的最好方法。

或者,您可以在文件上使用修改后的时间 - 文件必须是新的,并且修改后的时间至少是过去的 x。但我认为这将相当于缓存列表。

如果您每隔几秒钟就轮询一次文件夹,那么它的时间损失不是很大吗?并且它与平台无关。

此外,仅限 Linux:http ://www.linux.com/feature/144666

像 cron 但用于文件。不确定它如何处理您的特定问题 - 但可能有用吗?

于 2008-12-05T10:21:53.837 回答
0

你的操作系统是什么。在 unix 中,您可以使用“lsof”实用程序来确定用户是否打开了文件以供写入。显然,在 MS Windows 进程资源管理器中的某个地方有相同的功能。

或者,您可以尝试对文件进行独占打开并避免失败。但这可能有点不可靠,而且很容易踩到你自己的脚趾。

于 2008-12-05T10:55:14.673 回答