PHP:如何避免读取使用FTP推送给我的部分文件?

时间:2011-04-29 01:23:49

标签: php ftp locking

文件正在通过FTP推送到我的服务器。我在Drupal模块中使用PHP代码处理它们。 O / S是Ubuntu,FTP服务器是vsftp。

我将定期检查新文件,使用SimpleXML处理它们并将它们移动到“完成”文件夹。如何避免处理部分上传的文件?

vsftp将lock_upload_files默认为是。我想先尝试移动文件,期望在当前上传的文件中移动失败。这似乎不会发生,至少在命令行上。如果我开始上传大文件并移动,它只会在新位置继续增长。我猜目录条目没有锁定。

我是否应该尝试使用模式'a'或'r +'来查看它是否在尝试加载到SimpleXML之前成功还是有更好的方法来执行此操作?我想我可以检测到SimpleXML加载失败,但......看起来很麻烦。

我无法控制发件人。他们不会上传和重命名。

由于

7 个答案:

答案 0 :(得分:4)

使用lock_upload_files的{​​{1}}配置选项会导致使用vsftpd功能锁定文件。这会在正在进行的上传文件上放置咨询锁。其他程序不需要考虑咨询锁,例如fcntl()不会。咨询锁通常只是关心此类锁的程序的建议。 您需要另一个命令行工具,如mv,它尊重顾问锁。

注意:必须使用lockrun宏编译lockrun以使用WAIT_AND_LOCK(fd)而不是lockf()函数才能使用flock()设置的锁。 Linux下的1}}因此,当使用fcntl()编译lockrun时,它将与lockf()设置的锁合作。

使用此类功能(vsftpdlockrunmv),您可以构建一个shell脚本或类似程序,逐个移动文件,检查文件是否已事先锁定并持有只要文件被移动,就会对它进行咨询锁定。如果文件被lock_upload_files锁定,则vsftpd可以跳过对lockrun的调用,以便跳过正在运行的上传。

答案 1 :(得分:3)

如果锁定不起作用,我不知道你想要的解决方案是干净/简单。您可以通过不处理上次修改时间(您可以使用filemtime()获得)的文件在过去 x 分钟内处理文件,从而做出有根据的猜测。

如果您想要更高的置信度,可以在一个简单的数据库中检查并存储每个文件的大小(使用filesize()),并且每个 x 分钟检查新的大小它的旧尺寸。如果 x 分钟内的大小没有变化,您可以假设没有其他内容被发送。

答案 2 :(得分:2)

lsof linux命令列出了系统上打开的文件。我建议用PHP中的shell_exec()执行它并解析输出以查看FTP服务器仍在使用哪些文件。

答案 3 :(得分:1)

选择上一个答案,您可以复制文件,然后以固定间隔比较复制文件和原始文件的大小。

如果尺寸匹配,则上传完成,删除副本,使用文件。

如果尺寸不匹配,请再次复制文件。

重复。

答案 4 :(得分:0)

这是另一个想法:创建一个可以访问部分或全部上传目录的超级(但希望不是root)FTP用户。而不是您的PHP代码从磁盘上读取上传的文件,使其连接到本地FTP服务器并下载文件。这样,vsftpd会为您处理锁定(假设您启用了lock_upload_files)。一旦vsftp释放独占/写锁定(写入完成后),您将只能下载文件。

您提到在评论中尝试flock(以及它如何失败)。尝试匹配vsftpd所做的任何锁定确实显得很痛苦,但dio_fcntl可能值得一试。

答案 5 :(得分:0)

我猜你几年前已经解决了你的问题,但仍然。

如果您使用某种模式查找所需的文件,您可以要求上传文件的一方使用不同的名称,并在上传完成后重命名该文件。

答案 6 :(得分:0)

您应该在proftp中查看“隐藏的商店”,更多信息在这里: http://www.proftpd.org/docs/directives/linked/config_ref_HiddenStores.html