如何使用Perl

时间:2018-03-22 16:57:52

标签: perl

我正在尝试读取嵌套在父zip文件中的txt文件。文件夹结构如下所示:

父级Zip文件: ParentFile.zip

内容: ParentFolder/Subfolder1/Subfolder2/File1.zip

File1.zip包含File1.txt,我试图在内存中阅读。我查看了Archive::Zip and Archive::Zip::MemberRead的文档。我找不到从成员列表中返回新zip对象的方法,以便我可以使用以下方法。

$fh  = Archive::Zip::MemberRead->new($zipObj, "File1.txt");

我试图读取的文件是200MB,我需要遍历300个这样的文件。 ParentFile.zip位于网络驱动器上,我只能读取它。我试图找出如何将zip文件解压缩到我的本地驱动器。我找到了以下方法,但是当我有一个嵌套结构时似乎没有帮助。

use strict;
use Archive::Zip; 

my $destinationDirectory = 'C:\test'; 
my $zipObj = Archive::Zip->new('\\NetworkDrive\ParentFile.zip'); #SourceFile Path
#Cannot do below - No write permission on the network drive 
$zipObj->extractMember('ParentFolder/Subfolder1/Subfolder2/File1.zip')     

#Cannot do below as well since i have a folder structure
foreach my $member ($zip-> members()){
    my $extractName = $member->fileName;         
    $member->extractToFileNamed("$destinationDirectory/$extractName");
}

3 个答案:

答案 0 :(得分:1)

200MB不是一个大文件,在完成一些时间之前,你不应该预测代码中的瓶颈

File1.zip被加倍压缩为ParentFile.zip。如果不至少扩展后者的相关部分,就无法从前者中提取信息

除非File1.zip是巨大的(zip格式允许将数GB的简单数据压缩到几百字节),否则您应该简单地提取整个文件并在第二步中处理它

如果您非常绝望,那么有办法提取zip文件中的项目列表而无法访问整个内容,但我认为这不会对您有所帮助

答案 1 :(得分:1)

您可以使用IO::Uncompress::Unzip处理嵌套的zip文件,而无需解压缩完整的嵌套zip文件。

以下是一个展示其运作方式的示例。

在我的测试设置中,我有一个名为outer.zip的zip文件,其中包含inner.zip。

$ unzip -l outer.zip 
Archive:  outer.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      185  03-23-2018 12:53   inner.zip
---------                     -------
      185                     1 file

inner.zip包含我们想要访问的文件。

$ unzip -l inner.zip 
Archive:  inner.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       14  03-23-2018 12:53   payload.txt
---------                     -------
       14                     1 file

在这种情况下,它只包含几行文字。

$ cat payload.txt 
line 1
line 2

下面的脚本将从内部zip读取有效内容数据并写入output.txt。

#!/usr/bin/perl

use warnings;
use strict;

use IO::Uncompress::Unzip qw(unzip) ;

my $outer = "outer.zip";
my $inner = "inner.zip";
my $data = "payload.txt";
my $output = "output.txt";

my $z = new IO::Uncompress::Unzip $outer, Name => $inner
    or die "Cannot open $outer\n";

unzip $z => $output, Name => $data
    or die "Cannot unzip $inner";

这是我在output.txt中看到的

$ cat output.txt 
line 1
line 2

答案 2 :(得分:0)

  

我想读的文件是200MB,我不想提取。

您可能需要提取它。

如果内部ZIP文件已缩小,则无法选择 - 您无法在缩小的流中进行搜索,并且无法在不寻求的情况下读取ZIP存档。 (目录存储在存档的末尾。)

如果内部ZIP文件存储(即未压缩),从技术上讲可能将存储的内容视为ZIP存档,但我不知道有任何方法可以使Archive :: Zip执行这一点。