1

我正在尝试即时构建一个压缩的 xml 文件并将其发送到浏览器。我正在使用IO::Compress::Zipwith IO::String,但它不像文档中所期望的那样工作。

首先我的代码:

my $zipped_file;
foreach (@{$par{directory}}) {
    my $input = IO::String->new($_->[0]);
    zip $input => \$zipped_file, Append => 1, BinModeIn => 1|0; # Tried both for BinModeIn
}
return $zipped_file;

$par{directory}是一个具有以下结构的arrayref:

[
    ['DATA', 'FILENAME'], ['DATA', 'FILENAME'], ...
]

中的数据$par{directory}是这样的字符串:

<?xml version="1.0" encoding="UTF-8"?>
<derivatives>
     <derivative ag="111520420" vhash="d6712f201155a9afb64dc5a5ba369c99">
        //Some data
    </derivative>
</derivatives>

当我尝试将文件下载为带有一个空文件的 .zip 存档时,我得到的只是。关于我在这里做错了什么的任何提示?

提前致谢。

编辑:这很奇怪。我现在已经尝试过了:

use strict;
use warnings;
use IO::Compress::Zip 'zip';

my $xml1 = <<END_XML;
    <?xml version="1.0" encoding="UTF-8"?>
    <derivatives>
        <derivative ag="111520420" vhash="d6712f201155a9afb64dc5a5ba369c99">
            //Some data
        </derivative>
    </derivatives>
END_XML  

my $xml2 = <<END_XML;
    <?xml version="1.0" encoding="UTF-8"?>
    <derivatives2>
         <derivative2 ag="111520420" vhash="d6712f201155a9afb64dc5a5ba369c99">
             //Some data
         </derivative2>
     </derivatives2>
END_XML  

my $files = [[$xml1, 'xml1'], [$xml2, 'xml2']];
my $zipped_file;

foreach (@$files) {
    open my $input, '<', \$_->[0];
    zip $input => \$zipped_file, Append => 1, BinModeIn => 1;
}

open my $fh, '>:raw', 'zip.zip';
print $fh $zipped_file;
close $fh;

存档仍然是空的。

4

2 回答 2

1

zip的Append选项没有达到您的预期。它不会更新现有的 zip 文件。它创建一个新的并将其附加到您提供的文件/缓冲区中。在您的情况下,您最终会得到一系列背靠背的 zip 容器。

这是一种使用 Archive::Zip::SimpleZip 实现您想要的方法 - 这只是 IO::Compress::Zip 的包装器,用于处理这种类型的用例。

use Archive::Zip::SimpleZip ;

my $zipped_file;
my $zip = new Archive::Zip::SimpleZip \$zipped_file ;
foreach (@{$par{directory}}) {
  $zip->addString($_->[0], Name => $_->[1]);
}
$zip->close();
return $zipped_file;
于 2013-04-23T14:08:34.507 回答
0

我认为问题更可能出$zipped_file在您创建它之后所做的事情。

下面的程序对我有用。我已将压缩字符串写入二进制文件,并使用单独的实用程序将其解压缩以提供原始 XML。

我宁愿放弃IO::String并使用内置的open my $input, '<', \$_->[0],但它似乎可以工作。

use strict;
use warnings;

use IO::Compress::Zip 'zip';
use IO::String;

my $xml = <<END_XML;
<?xml version="1.0" encoding="UTF-8"?>
<derivatives>
     <derivative ag="111520420" vhash="d6712f201155a9afb64dc5a5ba369c99">
        //Some data
    </derivative>
</derivatives>
END_XML

my $zipped_file;

my $input = IO::String->new($xml);

zip $input => \$zipped_file, Append => 0, BinModeIn => 1;

open my $fh, '>:raw', 'zip.zip';
print $fh $zipped_file;
close $fh;

更新

顺便说一句,似乎根本不需要打开输入数据的 IO 流:您只需传递对包含数据的标量的引用即可。所以上面就变成了

my $zipped_file;

zip \$xml => \$zipped_file, Append => 0, BinModeIn => 1;

open my $fh, '>:raw', 'zip.zip';
print $fh $zipped_file;
close $fh;
于 2013-04-23T12:28:13.217 回答