如何使用Net :: FTP从FTP服务器上的文件夹下载所有*.xml
文件?
我看到glob()
将是最好的方式,但我无法绕过逻辑。
我需要检查文件夹中是否有XML文件。如果没有,请等待5秒钟,然后再次检查。一旦文件出现,我需要下载它们并通过我已经工作的Java应用程序运行它们。
如何监视特定文件类型的文件夹,并在出现时自动ftp->get
这些文件?
当我需要在ftp站点上获得过滤的文件列表时,我使用grep
和Net :: FTP的ls
方法。
警告,未经测试的代码:
#!/usr/bin/perl
use strict;
use warnings;
use Net::FTP;
#give END blocks a chance to run if we are killed
#or control-c'ed
$SIG{INT} = $SIG{TERM} = sub { exit };
my $host = shift;
my $wait = 5;
dbmopen my %seen, "files_seen.db", 0600
or die "could not open database: $!";
while (1) {
my $ftp = Net::FTP->new($host, Debug => 0)
or die "Cannot connect to $host: $@";
END { $ftp->quit if $ftp } #close ftp connection when exiting
$ftp->login("ftp",'ftp') #anonymous ftp
or die "Cannot login: ", $ftp->message;
for my $file (grep { /[.]xml$/ and not $seen{$_} } $ftp->ls) {
$ftp->get($file)
or die "could not get $file: ", $ftp->message;
#system("/path/to/javaapp", $file) == 0
# or die "java app blew up";
$seen{$file} = 1;
}
sleep $wait;
}
这样的事情怎么样?这当然会被你的代码每X秒调用一次。
my %downloaded;
sub check_for_new {
# Get all files
my @files = $ftp->ls;
foreach $f (@files) {
# Check if it is an XML file
if($f =~ /\.xml$/) {
# Check if you already fetched it
if(!$downloaded{$f}) {
if($ftp->get($f)) {
$downloaded{$f} = 1;
} else {
# Get failed
}
}
}
}
}
如果需要重新下载可能已更改的xml文件,则还需要进行文件比较,以确保本地副本与ftp服务器上的远程副本同步。
use Cwd;
use Net::FTP;
use File::Compare qw(compare);
my %localf;
my $cdir = cwd;
sub get_xml {
for my $file ($ftp->ls) {
##Skip non-xml files
next if $file !~ m/\.xml$/;
##Simply download if we do not have a local copy
if (!exists $localf{$file}) {
$ftp->get($file);
$localf($file) = 1;
}
##else compare the server version with the local copy
else {
$ftp->get($file, "/tmp/$file");
if (compare("$cdir/$file", "/tmp/$file") == 1) {
copy("/tmp/$file", "$cdir/$file");
}
unlink "/tmp/$file";
}
}
}
我直接将其输入到回复框中,因此在实施之前可能需要进行一些修饰和错误检查。对于外部逻辑,您可以编写一个建立ftp连接的循环,调用此子例程,关闭连接并在'n'秒内休眠。