2011-04-29 66 views
13

文件正通过FTP被推送到我的服务器。我在Drupal模块中用PHP代码处理它们。 O/S是Ubuntu,FTP服务器是vsftp。PHP:我如何避免阅读使用FTP推送给我的部分文件?

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

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

我应该试着用模式'a'还是'r +'来试图加载到SimpleXML之前是否成功?还是有更好的方法来做到这一点?我想我可以检测到SimpleXML加载失败,但...似乎凌乱。

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

感谢

+1

如果检查锁不起作用,也许您可​​以查看该文件的上次修改时间以查看它是否仍在/仍在被触摸。 – deceze 2011-04-29 01:34:50

回答

3

如果锁不工作,我不知道,只要你愿意为清洁/简单的解决方案的。您可以通过不处理上次修改时间(可使用filemtime()得到的文件)在过去的x分钟内的文件来进行有根据的猜测。

如果你想有一个更高的程度比信心,你可以检查和(使用filesize())在一个简单的数据库存储每个文件的大小,每X分钟核对其原始尺寸的新的大小。如果尺寸在x分钟内没有变化,您可以假定没有更多内容正在发送。

+0

谢谢。 filemtime似乎是最简单的解决方案。他们只是我每小时检查一次的小文件,所以如果它在最后一分钟没有写入,我应该没问题。我试过fopen,然后得到了一个与羊群排他锁,但它总是成功。我想我不明白vsftp在lock_upload_files = YES或真正关于锁定的时候会做什么。我确实了解咨询锁的概念,所以我想这不是vsftp使用的。 – tetranz 2011-04-29 14:06:47

1

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

如果大小匹配,上传完成,删除副本,使用文件。

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

重复。

2

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

4

使用lock_upload_files配置选项vsftpd导致使用fcntl()函数锁定文件。这将在正在进行的上传文件中放置顾问锁。其他程序不需要考虑咨询锁,例如mv则不需要。咨询锁一般只是关心这类锁的程序的建议。 您需要另一个命令行工具,如lockrun尊重咨询锁。

注:lockrun必须与WAIT_AND_LOCK(fd)宏编译使用lockf(),而不是flock()功能,以便与由fcntl() Linux下设置锁定工作。因此,当使用lockf()编译lockrun时,它将与由vsftpd设置的锁配合使用。

由于这种特征(lockrunmvlock_upload_files),你可以建立一个移动的文件一个接一个,如果该文件是事先锁定检查并在其上持有一个咨询锁,只要一个shell脚本或类似的文件被移动。如果文件被vsftpd锁定,则lockrun可跳过呼叫mv,以便跳过正在运行的上载。

0

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

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

0

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

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