2010-02-11 7 views
0

Je me demande comment je voudrais télécharger tous les fichiers * .xml à partir d'un dossier que j'ai configuré sur un serveur FTP en utilisant Net :: FTP. J'ai vu que glob() serait le meilleur moyen, mais je ne peux pas tout à fait envelopper la tête autour de la logique.Comment télécharger sur FTP tous les fichiers XML d'un répertoire?

Fondamentalement, je dois vérifier s'il y a des fichiers XML dans le dossier. Si ce n'est pas le cas, attendez 5 secondes et vérifiez à nouveau. Une fois que les fichiers apparaissent, j'ai besoin de les télécharger et de les exécuter via une application Java (cette partie que j'ai déjà descendu). Donc, merveilleux assistants anonymes, comment puis-je surveiller un dossier pour un type de fichier spécifique, et automatiquement ftp->get ces fichiers quand ils apparaissent?

Merci!

+0

sont les fichiers xml mutable? Autrement dit, subissent-ils des modifications après le téléchargement initial? Si oui, je suppose que vous devez également télécharger le fichier mis à jour. Correct? – aks

Répondre

2

Lorsque j'ai besoin d'une liste filtrée de fichiers sur un site FTP, j'utilise grep avec la méthode ls de Net :: FTP.

avertissement, code non testé:

#!/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: [email protected]"; 

    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

Fonctionne parfaitement, merci! Maintenant, je dois juste surmonter quelques problèmes qui ont surgi dans l'application Java ... – ryantmer

0

Qu'en est-il de quelque chose comme ça? Ce serait bien sûr appelé toutes les X secondes par votre code.

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 
       } 

      } 
     } 
    } 

} 
0

Si vous avez besoin de re-télécharger des fichiers XML qui auraient pu changer alors vous devez aussi faire un fichier comparer pour vous assurer que votre copie locale est en phase avec la copie à distance sur le serveur 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"; 
    } 
    } 
} 

Je dactylographiées ceci directement dans la zone de réponse de sorte qu'il pourrait avoir besoin avant vérification jeté mis en œuvre quelques retouches et erreur. Pour la logique externe, vous pouvez écrire une boucle qui établit la connexion ftp, appelle ce sous-programme, ferme la connexion et dort pendant 'n' secondes.

Questions connexes