您的位置:首页 > 编程语言 > PHP开发

监听FTP服务器来获取读写完成的文件

2017-10-16 09:19 661 查看

问题场景

文件通过ftp客户端上传到ftp服务器,服务器段需要及时的把读写完成的文件保存到其他storage中(或者处理)。这就需要保证监听程序能够监听该文件,判断该文件已经被写完成了,才能够做后续处理,否则接受到的是一个不完成的文件。(主要场景是ftp客户端上传的文件是不可控的,就是不是你自己控制的。所以加校验码、文件名后缀等方式不可行) 类似的问题在stackoverflow 

当然,比较合理的方式有;

通过文件状态判断文件是否写入完成

I use ftputil to
implement this work-around:

connect to ftp server

list all files of the directory

call stat() on each file

wait N seconds

For each file: call stat() again. If result is different, then skip this file, since it was modified during the last seconds.

If stat() result is not different, then download the file.

This whole ftp-fetching is old and obsolete technology. I hope that the customer will use a modern http API the next time :-)
 1、监听服务目录
2、获取所有该目录下文件的状态,比如最后修改时间

3、等一段时间。(这个时间是需要实验的,不能太短,有可能文件还没被写完,要考虑ftp的文件缓存是否被flush)

4、再次获取文件状态,如果有不同,说明文件还在没写入,否则文件已经写完。

依赖与ftp服务器的文件锁

down
vote
In theory the FTP server may lock the uploaded file from being accessed by other processes or other FTP connections.

In practice, it's not happening on *nix servers. I've tested this on CentOS with PureFTPD and ProFTPD (the most widely used *nix FTP servers). With both servers, nothing prevents you from downloading an incomplete file.

On the other hand, Windows IIS FTP server does lock the uploaded file. Tested on IIS 6.2 (Windows 8.1).

For workaround see my answer at FileZilla
uploads are not atomic.

理论上,ftp做文件上传的时候,服务端需要对该文件做加锁处理,保证该文件不被读写,类似于数据库的排它锁,事务未被commit之前是不会释放的,其他事物无法访问该事务中的数据(排他性),但是实际上,很多linux服务端的ftp都不支持这种措施,他们都不保证上传上来的文件在写入完成期间是加锁或者做类似处理的。


Locking files while uploading / Upload to temporary file name

Common workarounds are:

Upload “done” file once an upload of data files finishes and have
the automated system wait for the "done" file before processing the data files. This is easy solution, but won’t work in multi-user environment.

Upload data files to temporary (“upload”) folder and move them atomically to target folder once the upload finishes.

Upload data files to distinct temporary name, e.g. with 
.filepart
 extension, and rename them atomically
once the upload finishes. Have the automated system ignore the 
.filepart
 files.

通用的处理办法是:
1、等待文件写入完成,然后再处理该文件,就是通过监听文件状态,等待一段时间在判断一次,未改变则文件写完,否则再等待。

这种方式很简单,但是在多用户环境下是无法正常起作用的。

2、上传到一个临时目录,然后等写完之后移动到目标目录,这个得要服务器实现,谁做上传文件的,谁来实现这个功能,如果是ftp的话,就要看这个ftp server是否支持此操作了。

3、上传时使用一个不同的临时文件,例如.filepart后缀的文件,等读写完成之后改成目标文件名。

具体的code实现, https://winscp.net/eng/docs/script_locking_files_while_uploading

参考:
https://stackoverflow.com/questions/14452456/how-to-know-if-file-is-complete-on-the-server-using-ftp https://coderanch.com/t/328015/java/Check-ftp-download-files-finish http://java.ittoolbox.com/groups/technical-functional/java-l/how-to-know-when-a-file-is-finished-copying-in-java-5534424 http://www.perlmonks.org/?node_id=291634
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: