2017-05-08 211 views
3

cronjob每隔3小时运行一次使用SFTP下载文件。预定的程序是用Perl编写的,使用的模块是Net::SFTP::ForeignSFTP文件同时上传和下载

能否Net::SFTP::Foreign下载文件仅部分使用SFTP上传?

如果是这样,我们需要检查修改日期,检查复制过程完成SFTP文件?

假设一个新的文件被人在SFTP上传和他文件上传/复制过程中。如果同时尝试下载,是否需要编写只读取文件的一部分的可能性?

回答

2

这不是SFTP 客户您使用的问题,这是无关紧要的。这就是SFTP 服务器如何处理这种情况。

一些SFTP服务器可能锁定文件被上传,导致您无法访问它,而仍然被上传它。但是大多数SFTP服务器,特别是常见的OpenSSH SFTP服务器,不会锁定文件。

这个问题没有通用的解决方案。检查时间戳或大小更改可能适用于您,但它几乎不可靠。

有一些常见的解决方法的问题:

  • 有上传上传“完成”文件上传一次完成。让你的程序等待“完成”文件出现。
  • 你可以有专门的“上传”文件夹,并让上传者(自动)将上传的文件移动到“完成”文件夹中。只让你的程序看起来“完成”文件夹。
  • 对上传的文件有一个文件命名约定(“.filepart”),并在上传到其最终名称后让上传器(自动)重命名该文件。让你的程序忽略“.filepart”文件。
    有关实施此方法的示例,请参阅(我的)文章Locking files while uploading/Upload to temporary file name
  • 严重的黑客攻击是定期检查文件属性(大小和时间),并考虑上传完成,如果属性在某段时间内没有改变。

有关详细信息,请参阅我对SFTP file lock mechanism的回答。

0

您可以检查文件的大小。

  1. 连接到SFTP。
  2. 检查文件大小。
  3. 睡眠5/10秒。
  4. 再次检查文件大小。
  5. 如果大小没有改变,下载文件,如果大小改变执行步骤3.
1

这样做,当上传过程也是你的操控下最简单的方法,就是上传使用时间名称的文件(例如,foo-20170809.tgz.temp),一旦上传完成,重命名然后(Net::SFTP::Foreign::put方法支持atomic选项,就是这样做)。然后在下载端,用与时态文件相对应的名称过滤出文件。

无论如何,Net::SFTP::Foreigngetrget方法可以被指示通过选项resume => 1恢复转移。另外,如果你有完整的SSH访问SFTP服务器,你可以使用fuser或类似的工具(尽管如此,请注意,即使这样,文件可能仍然在写入要下载的文件如果例如存在一些网络问题并且上传者在恢复传输之前需要重新连接),则不完整。