1

私は Java BufferedReader オブジェクトを使用して、1,000 行の ASCII テキストを典型的な CSV 形式で含む有効な GZIP アーカイブを指す GZIPInputStream を 1 行ずつ読み取ります。コードは次のようになります。

BufferedReader buffer = new BufferedReader(new InputStreamReader(
                        new GZIPInputStream(new FileInputStream(file))));

file は、アーカイブを指す実際の File オブジェクトです。

私は呼び出してすべてのファイルを読みました

int count = 0;
String line = null;

while ((line = reader.readLine()) != null)
{
    count++;
}

リーダーは期待どおりにファイルを調べますが、最後に行 #1000 をバイパスし、もう 1 行読み取ります (つまり、ループの終了後にカウント = 1001)。

最後の行でline.length()を呼び出すと、多数 (4,000 以上) の文字が報告され、それらはすべて印刷できません ( Character.getNumericValue()は -1 を返します)。

実際、line.getBytes()を実行すると、結果の byte[] 配列には同じ数の NULL 文字 ('\0') が含まれます。

これは BufferedReader のバグのように見えますか?

いずれにしても、この動作を回避するための回避策を提案してもらえますか?

編集:さらに奇妙な動作: 読み取られる最初の行には、ファイル名、いくつかの NULL 文字 ('\0')、および行のユーザー名とグループ名がプレフィックスとして付けられ、その後に実際のテキストが続きます!

編集: 少なくとも私のプラットフォームでは、上記の効果を再現する非常に単純なテスト クラスを作成しました。

編集:どうやら誤報のようです。私が取得していたファイルはプレーンな GZIP ではなく、tar された GZIP であったため、これで説明できます。さらにテストする必要はありません。みんな、ありがとう!

4

1 に答える 1

3

私はあなたの問題を見つけたと思います。

質問のソースで再現しようとしたところ、次の出力が得られました。

-------------------------------------
        Reading PLAIN file
-------------------------------------

Printable part of line 1:       This, is, line, number, 1

Line start (<= 25 characters): This__is__line__number__1

No NULL characters in line 1

Other information on line 1:
        Length: 25
        Bytes: 25
        First byte: 84

Printable part of line 10:      This, is, line, number, 10

Line start (<= 26 characters): This__is__line__number__10

No NULL characters in line 10

Other information on line 10:
        Length: 26
        Bytes: 26
        First byte: 84

File lines read: 10

-------------------------------------
        Reading GZIP file
-------------------------------------

Printable part of line 1:       This, is, line, number, 1

Line start (<= 25 characters): This__is__line__number__1

No NULL characters in line 1

Other information on line 1:
        Length: 25
        Bytes: 25
        First byte: 84

Printable part of line 10:      This, is, line, number, 10

Line start (<= 26 characters): This__is__line__number__10

No NULL characters in line 10

Other information on line 10:
        Length: 26
        Bytes: 26
        First byte: 84

File lines read: 10

-------------------------------------
        TOTAL READ
-------------------------------------

Plain: 10, GZIP: 10

これはあなたが持っているものではないと思います。なんで?ファイルを使用していtar.gzます。これはtarアーカイブ形式であり、さらにgzip圧縮です。GZipInputStream は gzip 圧縮を元に戻しますが、tarアーカイブ形式については何も知りません。

tar は通常、複数のファイルをまとめて圧縮するために使用されます。

編集: さらに奇妙な動作: 読み取られる最初の行には、ファイル名、いくつかの NULL 文字 ('\0')、および行のユーザー名とグループ名が前に付けられ、実際のテキストが続きます!

ファイルがある場合はtar、tar デコーダーを使用する必要があります。Java で tar ファイルを抽出するにはどうすればよいですか? いくつかのリンクを提供します (Ant の Tar タスクを使用するなど) 。 JTarもあります。

1 つのファイルのみを送信する場合は、gzip形式を直接使用することをお勧めします (これは、テストで行ったことです)。

しかし、gzip-stream が tar 形式を読み取ることを期待していることを除けば、どこにもバグはありません。

于 2011-06-28T20:50:52.153 に答える