web-dev-qa-db-ja.com

GZIPInputStreamの行ごとの読み取り

.gz形式のファイルがあります。このファイルを読み取るためのJavaクラスはGZIPInputStreamです。ただし、このクラスはJavaのBufferedReaderクラスを拡張しません。その結果、ファイルを1行ずつ読み取ることができません。このようなものが必要です

reader  = new MyGZInputStream( some constructor of GZInputStream) 
reader.readLine()...

私はJavaのReaderまたはBufferedReaderクラスを拡張するクラスを作成し、その変数の1つとしてGZIPInputStreamを使用します。

import Java.io.BufferedReader;
import Java.io.FileInputStream;
import Java.io.FileNotFoundException;
import Java.io.IOException;
import Java.io.Reader;
import Java.util.Zip.GZIPInputStream;

public class MyGZFilReader extends Reader {

    private GZIPInputStream gzipInputStream = null;
    char[] buf = new char[1024];

    @Override
    public void close() throws IOException {
        gzipInputStream.close();
    }

    public MyGZFilReader(String filename)
               throws FileNotFoundException, IOException {
        gzipInputStream = new GZIPInputStream(new FileInputStream(filename));
    }

    @Override
    public int read(char[] cbuf, int off, int len) throws IOException {
        // TODO Auto-generated method stub
        return gzipInputStream.read((byte[])buf, off, len);
    }

}

しかし、これを使用すると機能しません

BufferedReader in = new BufferedReader(
    new MyGZFilReader("F:/gawiki-20090614-stub-meta-history.xml.gz"));
System.out.println(in.readLine());

誰かが進む方法をアドバイスできます..

76
Kapil D

デコレータの基本的なセットアップは次のとおりです。

InputStream fileStream = new FileInputStream(filename);
InputStream gzipStream = new GZIPInputStream(fileStream);
Reader decoder = new InputStreamReader(gzipStream, encoding);
BufferedReader buffered = new BufferedReader(decoder);

このスニペットの重要な問題は、encodingの値です。これは、ファイル内のテキストの文字エンコードです。 「US-ASCII」、「UTF-8」、「SHIFT-JIS」、「ISO-8859-9」、…?何百もの可能性があり、通常、正しい選択はファイル自体から判断することはできません。帯域外チャネルを介して指定する必要があります。

たとえば、プラットフォームのデフォルトかもしれません。ただし、ネットワーク環境では、これは非常に脆弱です。ファイルを書き込んだマシンは、隣接するキュービクルにあるかもしれませんが、異なるデフォルトのファイルエンコーディングがあります。

ほとんどのネットワークプロトコルは、ヘッダーまたはその他のメタデータを使用して、文字エンコーディングを明示的に記録します。

この場合、ファイル拡張子から、コンテンツはXMLであるように見えます。 XMLは、この目的のためにXML宣言に「エンコード」属性を含めます。さらに、XMLはテキストとしてではなく、XMLパーサーで実際に処理する必要があります。 XMLを1行ずつ読み取ることは、脆弱で特別な場合のように思えます。

エンコードを明示的に指定しないと、 2番目の戒めに対してデフォルトのエンコードを危険にさらします!

133
erickson
GZIPInputStream gzip = new GZIPInputStream(new FileInputStream("F:/gawiki-20090614-stub-meta-history.xml.gz"));
BufferedReader br = new BufferedReader(new InputStreamReader(gzip));
br.readLine();
41
ChssPly76
BufferedReader in = new BufferedReader(new InputStreamReader(
        new GZIPInputStream(new FileInputStream("F:/gawiki-20090614-stub-meta-history.xml.gz"))));

String content;

while ((content = in.readLine()) != null)

   System.out.println(content);

Utilクラスで次のメソッドを使用し、必要なときにいつでも使用できます...

public static List<String> readLinesFromGZ(String filePath) {
    List<String> lines = new ArrayList<>();
    File file = new File(filePath);

    try (GZIPInputStream gzip = new GZIPInputStream(new FileInputStream(file));
            BufferedReader br = new BufferedReader(new InputStreamReader(gzip));) {
        String line = null;
        while ((line = br.readLine()) != null) {
            lines.add(line);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace(System.err);
    } catch (IOException e) {
        e.printStackTrace(System.err);
    }
    return lines;
}
0
Memin

こちらは一行です

try (BufferedReader br = new BufferedReader(
        new InputStreamReader(
           new GZIPInputStream(
              new FileInputStream(
                 "F:/gawiki-20090614-stub-meta-history.xml.gz"))))) 
     {br.readLine();}
0
Tamer