2014-09-25 70 views
1

我有以下代码:无限循环通过FTP读取文件用Perl

use strict; 
use warnings; 
use Net::FTP; 

my $counter; 

my $ftp = Net::FTP->new("ftp.metagenomics.anl.gov", Debug => 0) 
    or die "Cannot connect.\n"; 
$ftp->login() or die "Login problems.\n"; 
$ftp->cwd("/projects") or die "Cannot change directory.\n"; 

for my $directory ($ftp->ls) { 
    $ftp->cwd($directory); 
    my ($remote_file_content, $remote_file_handle); 
    open($remote_file_handle, ">", \$remote_file_content); 
    $ftp->get("metadata.project-" . $directory . ".json", $remote_file_handle) 
     or die "Get failed.\n"; 
    while (my $line = $remote_file_content) { 
     $counter++; 
     if ($line =~ /"biome":{"unit":"","required":"1","value":"([A-Za-z0-9_\-. ]*)",/) { 
      print $counter. "\t" . $directory . "\t" . $1 . "\n"; 
     } 
    } 
    close $remote_file_content; 
    $ftp->cwd(".."); 
} 

然而,第一个文件被读一遍又一遍......它就像一个无限循环,我不知道为什么它永远不会完成读取同一个文件。你有什么主意吗?

+1

您是否尝试过注释某些代码行以查看问题所在?如果您发现哪条线路导致问题,您是否做过任何阅读以查看**为什么**可能导致无限循环? – 2014-09-25 10:50:02

+0

跟踪您的各种文件名,从'ls'打印出列表,打开哪个目录等。 – TLP 2014-09-25 10:52:01

回答

1
while (my $line = $remote_file_content) { 
     $counter++; 
     if ($line =~ /"biome":{"unit":"","required":"1","value":"([A-Za-z0-9_\-. ]*)",/) { 
      print $counter."\t".$directory."\t".$1."\n"; 
     } 
    } 

这个循环,只会一次$remote_file_content是假的(即空的),因为你没有last或其他方式退出循环。 但是,在这个循环中你永远不会改变$remote_file_content。 这意味着,一旦你输入它,你将永远不会离开循环。

0

你是想分别处理还是作为整体处理文件中的每一行?

如果你这样做是作为一个整体,摆脱while循环,并做到这一点:

for my $directory ($ftp->ls) { 
    $ftp->cwd($directory); 
    my ($remote_file_content, $remote_file_handle); 
    open($remote_file_handle, ">", \$remote_file_content); 
    $ftp->get("metadata.project-" . $directory . ".json", $remote_file_handle) 
     or die "Get failed.\n"; 
    $counter++; 
    if ($remote_file_content =~ /"biome":{"unit":"","required":"1","value":"([A-Za-z0-9_\-. ]*)",/) { 
     print $counter. "\t" . $directory . "\t" . $1 . "\n"; 
    } 
    close $remote_file_handle; 
    $ftp->cwd(".."); 
} 

如果要单独处理的每一行:

for my $directory ($ftp->ls) { 
    $ftp->cwd($directory); 
    my ($remote_file_content, $remote_file_handle); 
    open($remote_file_handle, ">", \$remote_file_content); 
    $ftp->get("metadata.project-" . $directory . ".json", $remote_file_handle) 
     or die "Get failed.\n"; 
    foreach my $line (split "\n", $remote_file_content) { 
     $counter++; 
     if ($line =~ /"biome":{"unit":"","required":"1","value":"([A-Za-z0-9_\-. ]*)",/) { 
      print $counter. "\t" . $directory . "\t" . $1 . "\n"; 
     } 
    } 
    close $remote_file_handle; 
    $ftp->cwd(".."); 
} 

你关闭文件名而不是文件句柄,关闭失败,您只是不知道它,因为当变量超出范围时会自动调用close。