如何通过FTP下载目录中的所有XML文件?

时间:2010-02-11 23:56:30

标签: perl file ftp

如何使用Net :: FTP从FTP服务器上的文件夹下载所有*.xml文件?

我看到glob()是最好的方式,但我无法绕过逻辑。

我需要检查文件夹中是否有XML文件。如果没有,请等待5秒钟,然后再次检查。一旦文件出现,我就需要下载它们并通过我已经工作的Java应用程序运行它们。

如何监控特定文件类型的文件夹,并在这些文件出现时自动ftp->get

3 个答案:

答案 0 :(得分:2)

当我需要在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;
}

答案 1 :(得分:0)

这样的事情怎么样?这当然会被你的代码每隔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
                }

            }
        }
    }

}

答案 2 :(得分:0)

如果您需要重新下载可能已更改的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'秒内休眠。