Java GZIPInputStream逐行读取

Java GZIPInputStream逐行读取,java,file-io,filereader,gzipinputstream,Java,File Io,Filereader,Gzipinputstream,我有一个.gz格式的文件。用于读取此文件的java类是GZIPInputStream。 然而,这个类并没有扩展java的BufferedReader类。因此,我无法逐行读取文件。我需要这样的东西 reader = new MyGZInputStream( some constructor of GZInputStream) reader.readLine()... 我想创建一个扩展java的Reader或BufferedReader类的类,并使用GZIPInputStream作为其变量之一

我有一个.gz格式的文件。用于读取此文件的java类是GZIPInputStream。 然而,这个类并没有扩展java的BufferedReader类。因此,我无法逐行读取文件。我需要这样的东西

reader  = new MyGZInputStream( some constructor of GZInputStream) 
reader.readLine()...
我想创建一个扩展java的Reader或BufferedReader类的类,并使用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());
有人能告诉我怎么做吗

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

装饰器的基本设置如下:

InputStream fileStream = new FileInputStream(filename);
InputStream gzipStream = new GZIPInputStream(fileStream);
Reader decoder = new InputStreamReader(gzipStream, encoding);
BufferedReader buffered = new BufferedReader(decoder);
此代码段中的关键问题是
编码的值。这是文件中文本的字符编码。它是“US-ASCII”、“UTF-8”、“SHIFT-JIS”、“ISO-8859-9”吗…?有数百种可能性,而正确的选择通常无法从文件本身确定。它必须通过一些带外通道指定

例如,可能是平台默认设置。然而,在网络环境中,这是非常脆弱的。写入文件的机器可能位于相邻的隔间中,但具有不同的默认文件编码

大多数网络协议使用头或其他元数据来显式记录字符编码

在本例中,文件扩展名显示内容是XML。为此,XML在XML声明中包含“encoding”属性。此外,XML实际上应该用XML解析器处理,而不是作为文本处理。逐行读取XML似乎是一种脆弱的特殊情况


如果未明确指定编码,则使用默认编码将有风险

您可以在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;
}
公共静态列表readLinesFromGZ(字符串文件路径){
列表行=新的ArrayList();
文件文件=新文件(文件路径);
try(GZIPInputStream gzip=newgzipinputstream(newfileinputstream(file));
BufferedReader br=新的BufferedReader(新的InputStreamReader(gzip));){
字符串行=null;
而((line=br.readLine())!=null){
行。添加(行);
}
}catch(filenotfounde异常){
e、 printStackTrace(System.err);
}捕获(IOE异常){
e、 printStackTrace(System.err);
}
回流线;
}
这里只有一行

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

你的回答很好。简洁。。不过,埃里克森的回答更详细。谢谢,它奏效了。。。但是,不需要读卡器步骤。。我们还可以将其编写为GZIPInputStream gzip=newgzipinputstream(newfileinputstream(“F:/gawiki-20090614-stub-meta-history.xml.gz”);BufferedReader br=新的BufferedReader(新的InputStreamReader(gzip))@KapilD这让我很难过,你完全没有理解他关于编码的观点……正如你的评论和评论中的例子所示。重新阅读erickson的答案…可能超过30次。gzip命令如何知道编码?我想从世界各地的linux/unix服务器上读取大量文件。。。所以我想确保我做得对。。。文章提到的编码通常不能由文件本身决定。。。但是gzip-d命令似乎可以在没有单独输入的任何文件上工作。。。(这就是我现在使用的,但我想绕开)所以我想如果我能弄清楚gzip是如何知道编码的,我也能做到。任何人能给我指出正确的方向吗?@glyphx你的问题不清楚。您的意思是,在缺少关于内容类型的外部断言的情况下,如何识别gzip文件?一个提示是文件扩展名,另一个提示是文件头中存在幻数0x1F8B。但是,在实际处理整个过程之前,您无法知道文件是有效的gzip文件。gzip文件都是基于文本的文件,比如csv和pipedelim文件。我只想能够用java逐行直接读取这些文件。我可以gzip-d它们,然后逐行阅读它们,没问题。我只是对你关于必须指定编码的评论感到困惑。。。我想大多数文件都是ASCII码。。。但有些可能有亚洲字符,所以可能是UTF-8?我只是想确保我做得正确。。。这更清楚了吗?谢谢看看这个链接。这里展示了一种压缩和解压方法。为了世界上所有美好和正确的事物的爱,为了编写甚至有点价值的代码的开发人员的理智……请注意@erickson指出的编码!他是唯一指出这一点的答案,这让我想哭。
try (BufferedReader br = new BufferedReader(
        new InputStreamReader(
           new GZIPInputStream(
              new FileInputStream(
                 "F:/gawiki-20090614-stub-meta-history.xml.gz"))))) 
     {br.readLine();}