如何检测正在通过 FTP 上传文件

How to detect that a file is being uploaded over FTP

我的应用程序正在监视一组用户可以上传文件的文件夹。当文件上传完成后,我必须进行处理,但我不知道如何检测文件尚未上传完成。

有什么方法可以检测 FTP 服务器是否尚未释放文件?

这个问题没有通用的解决方案。

一些 FTP 服务器锁定正在上传的文件,阻止您在文件仍在上传时访问它。例如 IIS FTP 服务器就是这样做的。大多数其他 FTP 服务器没有。在 Prevent file from being accessed as it's being uploaded.

查看我的回答

该问题有一些常见的解决方法(最初发布在 SFTP file lock mechanism,但也与 FTP 相关):

  • 上传完成后,您可以让客户端上传“完成”文件。让您的自动化系统等待“完成”文件出现。

  • 您可以有一个专用的“上传”文件夹,并让客户端(自动)将上传的文件移动到“完成”文件夹。让您的自动化系统只查看“完成”文件夹。

  • 为正在上传的文件制定文件命名约定 (".filepart"),并让客户端在上传后(自动)将文件重命名为其最终名称。让您的自动化系统忽略“.filepart”文件。

    有关实施此方法的示例,请参阅(我的)文章 Locking files while uploading / Upload to temporary file name

    此外,一些 FTP 服务器内置了此功能。例如 ProFTPD 及其 HiddenStores directive.

  • 一个粗暴的 hack 是定期检查文件属性(大小和时间)并认为上传完成,如果属性在一段时间间隔内没有改变。

  • 您还可以利用某些文件格式具有清晰的文件结束标记(如 XML 或 ZIP)这一事实。所以你知道,文件不完整。


一些 FTP 服务器允许您配置一个挂钩,以便在上传完成时调用。你可以利用它。例如 ProFTPD 有一个 mod_exec module(参见 ExecOnCommand 指令)。

我使用 ftputil 来实现这个解决方法:

  1. 连接到 ftp 服务器
  2. 列出目录的所有文件
  3. 对每个文件调用 stat()
  4. 等N秒
  5. 对于每个文件:再次调用 stat()。如果结果不同,则跳过此文件,因为它在最后几秒内被修改。
  6. 如果 stat() 结果没有不同,则下载文件。

整个ftp-抓取是陈旧过时的技术。我希望客户下次使用现代 http API:-)

这是 FTP 传输的经典问题。我发现的唯一 mostly 可靠的方法是发送一个文件,然后发送第二个简短的 "marker" 文件,只是告诉收件人第一个文件的传输已完成。您可以使用文件命名约定,只检查第二个文件是否存在。

您可能会喜欢将第二个文件的内容作为第一个文件的校验和。然后你可以验证第一个文件。 (你没有第二个文件的问题,因为你只是等到文件大小 = 校验和大小)。

当然,这只有在您可以让发件人发送第二个文件时才有效。

如果您正在阅读特定扩展名的文件,请使用 WINSCP 进行文件传输。它将创建一个扩展名为 .filepart 的临时文件,并且在完全传输文件后将变为实际文件扩展名。

希望对大家有所帮助。