2016-12-08 3 views
2

bashには、gzippedファイルを連結することができ、結果は有効なgzippedファイルです。私の知る限りリコールとして、私はいつも(私の例を上記のリンクからコード)通常のgzipで圧縮されたファイルとして、これらの「連結」gzipで圧縮されたファイルを処理することができました:IO :: Uncompress :: Gunzipは、「連結」gzippedファイル内の最初の「元の」gzippedファイルの後に停止します。

Hello world! 
Howdy world! 

しかし出力

echo 'Hello world!' > hello.txt 
echo 'Howdy world!' > howdy.txt 
gzip hello.txt 
gzip howdy.txt 

cat hello.txt.gz howdy.txt.gz > greetings.txt.gz 

gunzip greetings.txt.gz 

cat greetings.txt 

、 Perlのcore IO::Uncompress::Gunzip moduleを使用してこの同じファイルを読み込もうとすると、最初の元のファイルを通過しません。ここでの結果は次のとおりです。ここで

./my_zcat greetings.txt.gz 
Hello world! 

my_zcatのためのコードは次のとおりです。

#!/bin/env perl 
use strict; 
use warnings; 
use v5.10; 

use IO::Uncompress::Gunzip qw($GunzipError); 

my $file_name = shift; 

my $fh = IO::Uncompress::Gunzip->new($file_name) or die $GunzipError; 

while (defined(my $line = readline $fh)) 
{ 
    print $line; 
} 

私は全く新しいgzipで圧縮されたファイルを作成する前に、ファイルを解凍した場合、私はこの問題を持っていない:

zcat hello.txt.gz howdy.txt.gz | gzip > greetings_via_zcat.txt.gz 
./my_zcat greetings_via_zcat.txt.gz 
Hello world! 
Howdy world! 

greetings.txt.gzgreetings_via_zcat.txt.gzの違いは何ですか?また、IO::Uncompress::Gunzipが正しく動作する理由はgreetings.txt.gzです?

このanswer to another questionに基づいて、私はIO::Uncompress::Gunzipがファイル間のメタデータのために壊れていると推測しています。しかし、greetings.txt.gzが有効なGzipファイルであるため、IO::Uncompress::Gunzipが動作することが期待されます。今(もちろん、多くのWindowsユーザーを支援しません)zcatからパイピングされるため

私の回避策:これはIO ::圧縮FAQセクションDealing with concatenated gzip filesで明示的に覆われている

#!/bin/env perl 
use strict; 
use warnings; 
use v5.10; 

my $file_name = shift; 

open(my $fh, '-|', "zcat $file_name"); 

while (defined(my $line = readline $fh)) 
{ 
    print $line; 
} 
+1

を必要とし、この質問は、モジュールのバグトラッカーに投稿されています。https://rt.cpan.org /Public/Bug/Display.html?id=119184 – melpomene

+0

@melpomeneありがとうございました。あなたは私にそれを打つ。 –

+0

@melpomeneチケットは[IO :: Compress](https://metacpan.org/pod/distribution/IO-Compress/lib/IO/Compress/FAQ.pod#Dealing-with-concatenated)に記載されているので解決済みとマークされています。 -gzip-files)を使ってこれに対処する 'MultiStream'オプションを使います。 –

答えて

3

。基本的には、IO :: Uncompress :: Gunzipオブジェクトを構築するときにMultiStreamオプションを含める必要があります。ここで

definition of the MultiStream optionです:

MultiStream => 0|1

入力ファイル/バッファは、複数の 圧縮データストリームが含まれている場合は、このオプションは 単一のデータストリームとして全体の多くを解凍します。 0

デフォルトだからあなたのコードは、参考のため、この変更

my $fh = IO::Uncompress::Gunzip->new($file_name, MultiStream => 1) or die $GunzipError; 
+0

それは完璧です。私は 'IO :: Uncompress :: Gunzip'を検索し、' IO :: Compress'文書へのヒットをスキップして覚えているので、今は大声で笑っています。 –

関連する問題