【问题标题】:Perl Net::FTP::Recursive: Can't download folder but files of subfoldersPerl Net::FTP::Recursive:无法下载文件夹但子文件夹的文件
【发布时间】:2018-11-10 11:41:39
【问题描述】:

我成功从 ftp-server 的子文件夹下载文件。但是如果我想从上层下载文件夹就不行了。

这是文件夹结构:

  • 文件夹 rwx r-x r-x
    • 子文件夹 1 rwx r-x r-x
      • file1 rw- r-- r--
      • file2 rw- r-- r--
    • 子文件夹 2 rxx r-x r-x
      • file3 rw- r-- r--
      • file4 rw- r-- r--

如果我使用这个:

$f1->cwd("/folder/subfolder1");
$f1->rget();
$f1->quit;

文件file1和file2将被下载。

如果我使用这个:

$f1->cwd("/folder");
$f1->rget();
$f1->quit;

由于超时,将不会下载任何内容并且程序已完成。我预计它将下载 subfolder1 和 subfolder2 以及子文​​件夹的内容。对此有什么解释吗?如何以下载子文件夹和文件的方式解决?

代码的详细说明是here

更新 1: 调试

调试

my $f1 = Net::FTP::Recursive->new($host1, Debug => 1) or die "Can't open $host1\n";

给出以下内容:

Net::FTP::Recursive=GLOB(0x312bf50)>>> CWD /folder
Net::FTP::Recursive=GLOB(0x312bf50)<<< 250 CWD command successful
Net::FTP::Recursive=GLOB(0x312bf50)>>> PWD
Net::FTP::Recursive=GLOB(0x312bf50)<<< 257 "/folder" is the current directory
Net::FTP::Recursive=GLOB(0x312bf50)>>> PASV
Net::FTP::Recursive=GLOB(0x312bf50)<<< 227 Entering Passive Mode (188,40,220,103,255,187).
Net::FTP::Recursive=GLOB(0x312bf50)>>> LIST
Net::FTP::Recursive=GLOB(0x312bf50)<<< 150 Opening BINARY mode data connection for file list
Timeout at C:/Strawberry/perl/lib/Net/FTP.pm line 1107.

更新 2: 在 C:/Strawberry/perl/lib/Net/FTP.pm 第 1107 行超时。

_list_cmd 是调试输出中提到的行的函数。我还添加了使用 _list_cmd 的行并换行以使其更具可读性,同时保留行号。

 671 # Try to delete the contents
 672 # Get a list of all the files in the directory, excluding 
      #     the current and parent directories 
 673 my @filelist = map { /^(?:\S+;)+ (.+)$/ ? ($1) : () } 
          grep { !/^(?:\S+;)*type=[cp]dir;/i } $ftp->_list_cmd("MLSD", $dir);

 925 sub ls  { shift->_list_cmd("NLST", @_); }
 925 sub dir { shift->_list_cmd("LIST", @_); }


1087 sub _list_cmd {
1088   my $ftp = shift;
1089   my $cmd = uc shift;
1090 
1091   delete ${*$ftp}{'net_ftp_port'};
1092   delete ${*$ftp}{'net_ftp_pasv'};
1093 
1094   my $data = $ftp->_data_cmd($cmd, @_);
1095 
1096   return
1097     unless (defined $data);
1098 
1099   require Net::FTP::A;
1100   bless $data, "Net::FTP::A";    # Force ASCII mode
1101 
1102   my $databuf = '';
1103   my $buf     = '';
1104   my $blksize = ${*$ftp}{'net_ftp_blksize'};
1105 
1106   while ($data->read($databuf, $blksize)) {
1107     $buf .= $databuf;
1108   }
1109 
1110   my $list = [split(/\n/, $buf)];
1111 
1112   $data->close();
1114   if (EBCDIC) {
1115     for (@$list) { $_ = $ftp->toebcdic($_) }
1116   }
1117 
1118   wantarray
1119     ? @{$list}
1120     : $list;
1121 }

【问题讨论】:

  • 您可以为new 使用Debug 选项来查看它实际在做什么。也许这将有助于调试问题。
  • @Steffen 我使用了my $f1 = Net::FTP::Recursive-&gt;new($host1, DEBUG =&gt; 1) or die "Can't open \$f1 $host1\n";,它没有输出。您还有其他调试选项吗?
  • 它是Debug,而不是DEBUG。另请参阅the documentation 中的用法示例。
  • @Steffen 谢谢,我在我的问题中添加了调试信息。
  • 根据调试输出,在列出/folder 时,服务器似乎不会及时回复。鉴于它适用于/folder/subfolder1,它看起来像是服务器端问题,而不是Net::FTP::Recursive 的问题。

标签: perl ftp net-ftp


【解决方案1】:

要下载目录和文件,请尝试以下解决方法:对所有子目录使用循环并应用 rget。它完成了我想要的工作。尽管如此,rget 在上层不起作用的原因仍然没有得到解答。至少现在很明显这不是权限问题。

# ftp-server directory
my $ftpdir = "folder";

# Defie local download folder
my $download = "C:/local";
chdir($download);       

# Change to remote directory
$f1->cwd($ftpdir) or die "Can't cwd to $ftpdir\n", $f1->message;

# grep all folder of top level
my @ftp_directories = $f1->ls;

# remove . and ..
@ftp_subdir = grep ! /^\.+$/, @ftp_subdir;

foreach my $sd (@ftp_subdir) {

    # Make folder on local computer
    my $localdir = catfile($download,$sd);
    mkdir $localdir;

    # Change local working directory
    chdir $localdir;


    # Change to remote sub directory to be downloaded
    $f1->cwd($sd) or die "Can't cwd to $sd\n";
    }

    # download files
    $f1->rget();

    # Change to upper level
    $f1->cwd("..");
}  

$f1->quit;

【讨论】:

    猜你喜欢
    • 2016-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-02
    • 1970-01-01
    • 2020-07-17
    • 1970-01-01
    相关资源
    最近更新 更多