【问题标题】:Infinite loop reading files via FTP with Perl使用 Perl 通过 FTP 无限循环读取文件
【发布时间】:2014-11-20 02:10:21
【问题描述】:

我有以下代码:

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("..");
}

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

【问题讨论】:

  • 您是否尝试过注释掉某些代码行以查看问题所在?如果您发现是哪条线路导致了问题,您是否阅读过为什么它可能会导致无限循环?
  • 跟踪你的各种文件名,从ls打印出列表,打开哪个目录等等。

标签: perl file parsing ftp


【解决方案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。 这意味着,一旦你进入它,你将永远不会离开循环。

【讨论】:

    【解决方案2】:

    您是要单独处理文件中的每一行还是整体处理?

    如果您将其作为一个整体进行,请摆脱 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("..");
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-05
      • 2021-06-27
      • 2013-08-07
      相关资源
      最近更新 更多