如何检测文件正在通过 FTP 上传
Posted
技术标签:
【中文标题】如何检测文件正在通过 FTP 上传【英文标题】:How to detect that a file is being uploaded over FTP 【发布时间】:2015-05-28 02:09:48 【问题描述】:我的应用程序正在监视一组用户可以上传文件的文件夹。文件上传完成后,我必须应用处理,但我不知道如何检测文件尚未完成上传。
有什么方法可以检测文件是否还没有被 FTP 服务器释放?
【问题讨论】:
【参考方案1】:这个问题没有通用的解决方案。
某些 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 服务器内置了此功能。例如带有HiddenStores
directive 的 ProFTPD。
一个严重的技巧是定期检查文件属性(大小和时间),如果属性在一段时间内没有改变,则认为上传完成。
您还可以利用某些文件格式具有清晰的文件结束标记(如 XML 或 ZIP)这一事实。所以你知道,文件不完整。
某些 FTP 服务器允许您配置在上传完成时调用的挂钩。你可以利用它。例如,ProFTPD 有一个mod_exec module(参见ExecOnCommand
指令)。
【讨论】:
谢谢。由于我使用的是 IIS FTP 服务器,所以我只是等到文件解锁。【参考方案2】:我使用ftputil 来实现这个解决方法:
-
连接到 ftp 服务器
列出目录下的所有文件
对每个文件调用 stat()
等待 N 秒
对于每个文件:再次调用 stat()。如果结果不同,则跳过此文件,因为它是在最后几秒内修改的。
如果 stat() 结果没有不同,则下载文件。
整个 ftp 获取是陈旧过时的技术。我希望客户下次使用现代 http API :-)
【讨论】:
很容易将此归咎于旧协议,但这个问题与 HTTP 并没有太大区别。 @tcurdt 如果客户确实使用 http 向我们发送文件,那么我可以处理接收部分。我可以立即采取行动,我可以验证它,如果文件无效,我可以拒绝文件......至少在我的上下文中(我使用 Django)。 你说的是写一个http服务。如果您编写自己的 ftp 服务,您也可以这样做。那是没有争议的。尝试放在 webdav 服务器上。 FWIW proftpd 甚至有一个配置选项来打开两阶段上传。这是一个实施问题,而不是协议问题。 @tcurdt 是的,你是对的。你能给我一个易于使用的框架来实现 ftp 服务的建议,它允许我在接受数据之前验证数据吗? @Brood 60 秒。【参考方案3】:如果您正在读取特定扩展名的文件,请使用 WINSCP 进行文件传输。它将创建一个扩展名为 .filepart 的临时文件,并在完全传输文件后转换为实际文件扩展名。
希望对大家有所帮助。
【讨论】:
【参考方案4】:这是 FTP 传输的一个典型问题。我发现的唯一大部分可靠的方法是发送一个文件,然后发送第二个简短的“标记”文件,只是为了告诉收件人第一个传输完成。您可以使用文件命名约定并检查第二个文件是否存在。
您可能会喜欢将第二个文件的内容作为第一个文件的校验和。然后你可以验证第一个文件。 (第二个文件没有问题,因为您只需等到文件大小 = 校验和大小)。
当然,这只有在您可以让发件人发送第二个文件时才有效。
【讨论】:
就我而言,我无法影响 ftp 上传应用程序,也无法影响 ftp 服务器 :-( ... 但它是可以解决的(见上文) 这是一个聪明的解决方案——但我不知道我是否真的相信它(但是,我很偏执)。你是对的,当然,FTP sux。以上是关于如何检测文件正在通过 FTP 上传的主要内容,如果未能解决你的问题,请参考以下文章