2013-04-23 3 views
1

나는 압축 XML 파일을 즉시 작성하여 브라우저로 보내려고합니다. 나는 IO::Compress::ZipIO::String과 함께 사용하고 있지만 설명서에서 기대하는 바대로 작동하지 않습니다.IO :: Compress :: Zip을 파일 핸들에서 버퍼로 읽어들입니다.

먼저 내 코드 :

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입니다 :

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

모든 I : $par{directory}에서

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

데이터는이 같은 문자열입니다 한 emp로 .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; 

아카이브가 아직 비어 있습니다.

+0

시도가>는 \ $ zipped_file, 추가] => 1, 이름 => $ _-은> [1], BinModeIn => 1 =;' – pmqs

답변

1

추가]를하게 우편에 대한 옵션은 무엇을 기대하고 있지 않습니다. 기존 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; 
+0

저것은 작동합니다 :-D 'IO :: Compress :: Gzip'에'Archive :: Zip :: SimpleZip'과 비슷한 것이 있습니까? gzip과 zip을 모두 사용해야하기 때문에. – Vince

+0

죄송합니다, 보관 처리 :: Zip :: SimpleZip of Zip files. IO :: Compress :: Zip을 IO :: Compress :: Gzip으로 바꾼 다음 "zip"대신 "gzip"을 사용하면 원래의 접근 방식이 잘 작동합니다. 어떤 것 (시험 안 함) gzip \ $ _-> [0] => \ $ zipped_file, Append => 1, Name => $ _-> [1]; gzip 사양 (RFC 1952)은 연속적인 gzip 파일을 허용하므로 Append 옵션은이 경우 ok입니다. 브라우저에서 연결된 gzip 파일을 처리 할 수 ​​있는지 여부는 다른 이야기입니다. – pmqs

+0

음, Append => 0 및 하나의 파일만으로 내 접근 방식을 사용할 수 없습니까? – Vince

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; 
+0

나는 시도했다 그 방법도,하지만 그것은 나를 위해 밖으로 작동하지 않았기 때문에, 나는 파일 핸들로 그것을 시도. – Vince

+0

흠. 둘 다 똑같이 작동합니다. – Borodin

+0

이제 코드를 스크립트에 복사했지만 여전히 작동하지 않습니다. 오류가없고, 아무것도 없으며, 내가 지울 수없는 빈 우편 아카이브 (mapname : 변환 실패). 아카이브와 관련된 파일 이름을 전달할 수 없다는 사실과 관련이 있습니까? – Vince