正在上传文件时从 ftp 服务器下载文件

Download file from ftp server while file is yet being uploaded

我需要自动从分布在不同域的不同 FTP 服务中提取(获取)文件,这些服务全天候 24/7 接收文件。

我的问题是 FTP 服务通常允许在上传文件时下载文件。 This 是可以在互联网上找到的问题参考之一。

这会导致文件下载不完整。

我尝试使用 windows 服务器和 ftp FileZilla 客户端复制这种情况,并按预期获得了一半的文件,因此没有安全机制来防止这种情况发生。所以也许很简单,没有办法从客户端阻止它。

所以我的问题是是否有一些锚点,我的客户可以测试它以确保 ftp 服务器已经作为文件的整体。

我很难相信一个协议已经过时了,因为 ftp 不提供安全机制,所以我一定是遗漏了什么,或者这是设计使然。

更新 我正在用 C# 开发自动化,但任何技术提示都可以提供帮助。解决方案需要愚弄教授,因为它对业务至关重要。

更新2 上传的客户端很多,不可能一概而论。

更新3 这个问题类似于问题 ,但在 update2.

中有额外的限制。

我相信从客户端来说,你能做的不多。

最多,您可以在一段时间后 re-check 文件大小,看看它是否发生了变化,然后采取任何必要的步骤来获取新内容。

FTP 并非设计为使用 FTP 服务器在两个客户端之间实时交换数据的协议。如果要下载的文件仍在上传,则不会向客户端发出任何通知,在覆盖文件时也不会显示有人正在下载此文件。这不是 FTP 协议中的设计错误。真正的问题是您试图将协议用于其设计目的以外的目的。

所以你有这个场景:

[Publisher] --uploads file--> [FTP Server] --downloads file--> [You]

您有一个正在将文件上传到 FTP 服务器的发布者,并且您从同一个 FTP 服务器下载。也可以有不同的FTP个服务器实例,一个用于上传,一个用于下载,查看相同的目录,但变化不大。

现在,因为您正在查看同一目录,所以下载者会在文件系统条目创建后立即看到文件 - 当来自发布者的第一个字节甚至可能仍在传输中时。

基本上有三种解决方案:

  • 哨兵文件,由FTP 服务器或插件编写。上传文件时存在的“$originalFileName.lock”,或上传成功完成时写入的“$originalFileName.done”。
  • 将文件移动到不同的目录:FTP 服务器将文件从发布者写入的上传目录移动到您读取的下载目录。
  • 最不稳定:检查文件大小和时间。当您开始下载时,请记住 FTP 服务器报告的文件的时间戳和大小。下载完文件后,将您的值与记住的值进行比较。当它们不匹配时,从您完成的地方继续下载以获取剩余的字节,从头开始。例如,您可以确定 "A file is successfully uploaded if it hasn't grown in size for five minutes",但这不是很稳健 - 并且可能导致您等待五分钟。

我根据这个 post 和其他人的答案的输入创建了以下自动化解决方案,以解决我的问题,意思是:从不同的 FTP 服务器,从不同的服务器中提取文件品牌,在很可能发生并发的情况下。

使用此 post 中建议的信号文件或其他机制将需要强制客户改变他们与我们交互的方式,因此它是大多数情况下的解决方案,但不是我的特定问题的解决方案。

所以,我的解决方案是:

  1. 扫描文件夹,解析每个文件的文件名、数据和大小。
  2. 丢弃任何太新的文件。仅当文件日期早于几分钟时才会考虑下载。挂起可能导致此规则无法阻止并发。
  3. 重命名文件。失败了,跳出来。这种基于并发的方法,到目前为止已被证明是 100% 准确的。
  4. 下载重命名的文件。
  5. 检查传输大小并查看是否匹配大小属性(偏执检查)
  6. 从ftp服务器中删除成功传输的文件。

此解决方案允许我们集中轮询 ftp 个文件夹。