12

在本系统中,将使用 SFTP 将大型视频文件上传到服务器上的特定目录。我正在编写一个 PHP 脚本,用于将完全上传的文件复制到另一个目录。

我的问题是,什么是判断文件是否完全上传的好方法?我考虑记下文件大小,让脚本休眠几秒钟,再次读取大小,然后比较两个数字。但这似乎很笨拙。

4

5 回答 5

5

简单的

如果您只想要一种可以处理大多数用例的简单技术 - 编写一个过程来检查上次修改日期或(如问题中所示)文件大小,如果它在设定的时间内没有改变,比如 1 分钟,假设上传完成并处理它。事实上 - 你的问题几乎是另一个问题的重复,恰好显示了这一点。

强大的

轮询文件大小/上次修改时间的替代方法(连接缓慢或间歇性可能导致打开的上传被认为过早完成)是使用inotify监听文件何时完成写入。

侦听 IN_CLOSE_WRITE可以知道 ftp 上传何时完成更新特定文件。

我从未在 php 中使用过它,但从spartan 文档看来,它的工作方式与底层 lib 完全相同。

让 FTP 客户端为您工作

考虑到一些 ftp 程序是如何工作的,来自这个评论

值得一提的是,一些 ftp 服务器会创建一个隐藏的临时文件来接收数据,直到传输完成。即 .foo-ftpupload-2837948723 在与目标文件相同的上传路径

如果适用,从完成的文件名中,您可以判断 ftp 上传是否实际完成或在上传过程中停止/断开连接。

于 2012-08-20T13:41:24.393 回答
4

理论上,如果您被允许从 PHP 运行系统命令,您可以尝试使用pidof命令获取 sftp 服务器进程的 pid,然后使用lsof输出检查当前检查的上传文件是否存在打开的文件描述符。

于 2012-08-20T13:53:54.823 回答
1

在传输过程中,唯一知道文件实际大小的是您的 SFTP 客户端,也可能是 SFTP 服务器(不知道协议细节,因此服务器也可能知道。)除非您可以直接与 SFTP 服务器通信,否则您必须等待文件完成。每隔一段时间检查一下似乎很笨拙,但在这种情况下是相当不错的。这就是我们在我的项目中所做的。

如果您的轮询间隔非常短,则在处理可能会停顿几秒钟的上传时,它的弹性不是很大。所以只需将间隔设置为每分钟一分钟或类似的东西。假设您在基于 *nix 的平台上,您可以设置一个 cron 作业以每分钟运行一次(或任何轮询间隔)来为您运行脚本。

于 2012-08-20T13:37:08.860 回答
1

正如@jcolebrand 所说-如果您无法控制上传过程-除了猜测(文件大小/日期)之外,您实际上无能为力。我会寻找一个服务器软件,它允许您在某些服务器操作之前/之后执行挂钩/脚本(这里:文件传输完成)。我不确定是否存在这样的软件。作为最后的手段,您可以通过为自己添加这样的钩子来调整一些开源 SFTP 服务器以满足您的要求。

于 2012-08-20T13:39:09.017 回答
1

在原始问题下的推荐中提到了一个有趣的答案(但由于某些未知原因,该评论被删除):您可以尝试解析 SFTP 服务器日志以查找完全上传的文件。

于 2012-08-20T16:36:56.463 回答