同时进行 SFTP 文件上传和下载

3
一个cronjob每隔3个小时运行一次,使用SFTP下载一个文件。所用的计划程序是Perl编写的,使用的模块是Net::SFTP::ForeignNet::SFTP::Foreign能否下载只上传了部分内容的文件?
如果可以,那么我们需要检查SFTP文件的修改日期来检查复制过程是否完成吗?
假设有人在SFTP中上传了一个新文件,并且文件上传/复制正在进行中。如果同时尝试下载,我是否需要编写代码以获取文件的部分内容?
3个回答

3
这与您使用的SFTP客户端无关,而是取决于SFTP服务器如何处理此情况。
某些SFTP服务器可能会锁定正在上传的文件,从而防止您访问该文件。但大多数SFTP服务器(特别是常见的OpenSSH SFTP服务器)不会锁定该文件。
没有通用的解决方案来解决此问题。检查时间戳或大小更改可能适用于您,但这几乎不可靠。
有一些常见的解决方法:
  • 上传完成后,让上传者上传“done”文件。使你的程序等待“done”文件出现。

  • 您可以拥有专用的“上传”文件夹,并将上传程序(原子地)将已上传的文件移动到“完成”文件夹中。使您的程序仅查看“完成”文件夹。

  • 为正在上传的文件制定命名约定(“.filepart”),并在上传后由上传者(原子地)将文件重命名为其最终名称。使您的程序忽略“.filepart”文件。

    参见(我的)文章Locking files while uploading / Upload to temporary file name,以了解实施此方法的示例。

    此外,一些FTP服务器已经内置了这个功能。例如,ProFTPD与其HiddenStores directive

  • 一个粗暴的办法是定期检查文件属性(大小和时间),如果属性在一段时间间隔内未更改,则认为上传已完成。

  • 您还可以利用某些文件格式具有明确的文件结尾标记(如XML或ZIP)的事实。因此,您知道何时下载不完整的文件。

具体详情请查看我的回答SFTP文件锁机制


1
当上传过程也在您的控制下时,最简单的方法是使用临时名称上传文件(例如,foo-20170809.tgz.temp),一旦上传完成,就将其重命名(Net :: SFTP :: Foreign :: put 方法支持 atomic 选项,可以实现此操作)。然后,在下载方面,过滤掉与临时文件名称相对应的文件。
无论如何,Net :: SFTP :: Foreign get rget 方法都可以通过传递 resume => 1 选项来指示恢复传输。
此外,如果您拥有SFTP服务器的完全SSH访问权限,可以使用 fuser 或某些类似工具检查是否仍有其他进程正在写入要下载的文件(尽管请注意,即使这样,如果存在某些网络问题并且上传者需要重新连接才能恢复传输,则文件可能仍不完整)。

0

您可以检查文件的大小。

  1. 连接到SFTP。
  2. 检查文件大小。
  3. 等待5/10秒。
  4. 再次检查文件大小。
  5. 如果大小没有改变,则下载文件;如果大小已更改,请执行步骤3。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接