Как я могу загрузить через FTP все файлы XML в каталоге? - PullRequest
0 голосов
/ 12 февраля 2010

Как загрузить все файлы *.xml из папки на FTP-сервере, используя Net :: FTP?

Я видел, что glob() будет лучшим способом, но я не могу обернуть голову вокруг логики.

Мне нужно проверить, есть ли в папке файлы XML. Если нет, подождите 5 секунд и проверьте снова. Когда файлы появятся, мне нужно загрузить их и запустить через приложение Java, которое у меня уже работает.

Как я могу отслеживать папку для определенного типа файла и автоматически ftp->get эти файлы, когда они появляются?

Ответы [ 3 ]

2 голосов
/ 12 февраля 2010

Когда мне нужно получить отфильтрованный список файлов на FTP-сайте, я использую grep с ls методом Net :: FTP.

предупреждение, непроверенный код:

#!/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;
}
0 голосов
/ 12 февраля 2010

Если вам необходимо повторно загрузить 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 секунд.

0 голосов
/ 12 февраля 2010

Как насчет этого? Это, конечно, будет вызываться каждые 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
                }

            }
        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...