我有一个 Java 文件扫描器应用程序,它使用 FTP 不断扫描服务器上的目录。获取目录的文件列表并一一下载。另一方面,在服务器上,有一个写入这些文件的进程。如果我很幸运,我不会尝试下载不完整的文件,但是我如何确定服务器上的写入过程是否已完成并且文件句柄已关闭,并且文件已准备好下载?
我无法控制服务器上的写入过程。此外,我没有目录的写权限来尝试获取写句柄以检查是否已经打开了写句柄,因此此选项不在讨论范围内。
是否有解决此问题的 FTP 功能?
这是一个非常古老且众所周知的问题。
无法绝对确定 FTP 守护程序正在写入的文件是否完整。文件传输甚至有可能失败,然后重新启动并完成。您必须轮询文件的大小并设置时间限制,例如 5 分钟。如果在此期间大小未更改,则您认为文件已完成。
如果可能,处理文件的程序应该能够处理部分文件。
一个更好的选择是 rsync,它更加健壮和确定。它甚至可以配置(通过命令行选项)将数据最初写入临时位置,并在成功完成后将其移动到最终目标路径。如果文件存在于您期望的位置,则根据定义它是完整的。
一种可能的解决方案是首先上传具有不同文件名的文件(例如添加“.partial”),然后将其重命名为其最终名称。
如果服务器找到最终名称,则上传已完成。
如果您无法控制上传过程,那么根据定义,您所要求的内容是不可能的:文件上传可能由于网络问题或由于任何原因停止发送过程而停止。
接收端将观察到的只是传入流的关闭;无法保证数据不会被部分传输。
其他解决方法可能是检查数据结束标记或使用对发送服务器的请求来检查(在他们看来)传输是否已完成。
这比 FTP 更基本:即使这些文件是在本地计算机上创建的,读取这些文件也会遇到类似的问题。
如果您无法修改写作过程,则需要跳过一些障碍。没有一个很好,但有些比其他的更安全。
可靠、安全的解决方案需要改进写入程序。
您可以使用 Apache 通用 API 中的 Ftp 库 获取更多信息
boolean flag = retrieveFile(String remote, OutputStream local);
此标志检查输出流对当前文件可用。