在此系统中,SFTP将用于将大型视频文件上载到服务器上的特定目录。我正在编写一个PHP脚本,用于将完全上传的文件复制到另一个目录。
我的问题是,判断文件是否完全上传有什么好方法?我考虑过记录文件大小,睡眠脚本几秒钟,再次读取大小,并比较两个数字。但这似乎非常愚蠢。
答案 0 :(得分:5)
如果你只想要一个能够处理大多数用例的简单技术 - 写一个进程来检查最后修改日期或(如问题中所示)文件大小,如果它在设定时间内没有改变,说1分钟,假设上传完成并处理它。事实上 - 你的问题是另一个问题的near duplicate,显示了这一点。
轮询文件大小/上次修改时间(具有缓慢或间歇性连接可能导致开放上传过早被认为完成)的另一种方法是监听文件何时写完{{ 3}}
inotify您可以知道ftp上传何时完成更新特定文件。
我从来没有在php中使用过它,但是从Listening for IN_CLOSE_WRITE看起来它的工作方式与底层的lib完全相同。
考虑一些ftp程序的工作原理,来自spartan docs:
值得一提的是,一些ftp服务器会创建一个隐藏的临时文件来接收数据,直到传输完成。即.foo-ftpupload-2837948723与目标文件在同一个上传路径中
如果适用,从完成的文件名中,您可以判断ftp上传是否已实际完成,或者是在上传中停止/断开。
答案 1 :(得分:4)
理论上,如果允许您从PHP运行系统命令,您可以尝试使用 pidof 命令获取sftp服务器进程的pids,然后使用 lsof 输出以检查当前检查的上载文件是否存在打开的文件描述符。
答案 2 :(得分:1)
在传输期间,唯一知道文件实际大小的是您的SFTP客户端和SFTP服务器(不知道协议细节,因此服务器也可能知道。)除非您可以与SFTP服务器通信直接,然后你将不得不等待文件完成。在某个时间间隔检查似乎是kludgy但在这种情况下是相当不错的。这就是我们在项目中所做的事情。
如果您的轮询间隔非常短,那么在处理可能会停顿几秒钟的上传时,它的弹性并不是很大。所以只需将间隔设置为每分钟一次或类似的东西。假设你在基于* nix的平台上,你可以设置一个cron作业来每分钟运行一次(或者你的轮询间隔是什么)来为你运行你的脚本。
答案 3 :(得分:1)
正如@jcolebrand所说 - 如果你无法控制上传过程 - 除了猜测(文件的大小/日期)之外你实际上没什么可做的。我会寻找一个服务器软件,它允许你在一些服务器动作之前/之后执行钩子/脚本(这里:文件传输完成)。我不确定这种软件是否存在。作为最后的手段,你可以通过为自己添加这样一个钩子来适应一些开源SFTP服务器。
答案 4 :(得分:1)
在原始问题的推荐中提到了一个有趣的答案(但由于某些未知原因删除了注释):您可以尝试解析SFTP服务器日志以查找完全上传的文件。