Pergunta

Eu tenho um arquivo em formato .gz. A classe Java para ler este arquivo é GZIPInputStream. No entanto, essa classe não estender a classe BufferedReader de java. Como resultado, eu não sou capaz de ler o arquivo linha por linha. Eu preciso de algo como isto

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

I embora de criar minha classe que estende a classe Reader ou BufferedReader do Java e uso GZIPInputStream como uma de suas variáveis.

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);
    }

}

Mas, isso não funciona quando eu uso

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

Pode alguém conselhos como proceder ..

Foi útil?

Solução

A configuração básica de decoradores é assim:

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

A questão-chave neste trecho é o valor de encoding. Esta é a codificação de caracteres do texto no arquivo. É "US-ASCII", "UTF-8", "SHIFT-JIS", "ISO-8859-9", ...? existem centenas de possibilidades, ea escolha correta geralmente não pode ser determinado a partir do próprio arquivo. Deve ser especificado por meio de algum canal out-of-band.

Por exemplo, talvez seja o padrão plataforma. Em um ambiente de rede, no entanto, isso é extremamente frágil. A máquina que escreveu o arquivo pode sentar-se no cubículo vizinho, mas tem uma codificação de arquivo padrão diferente.

A maioria dos protocolos de rede usar um cabeçalho ou outros metadados notar explicitamente a codificação de caracteres.

Neste caso, resulta a extensão do arquivo que o conteúdo é XML. XML inclui o atributo "codificação" na declaração XML para esta finalidade. Além disso, XML deve realmente ser processado com um parser XML, não como texto. XML leitura linha-a-linha parece ser um caso frágil, especial.

não definir explicitamente a codificação é contra o segundo mandamento. Use o padrão codificação em seu perigo!

Outras dicas

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

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);

Você pode usar o seguinte método em uma classe util, e usá-lo sempre que necessário ...

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;
}

aqui é com uma linha

try (BufferedReader br = new BufferedReader(
        new InputStreamReader(
           new GZIPInputStream(
              new FileInputStream(
                 "F:/gawiki-20090614-stub-meta-history.xml.gz"))))) 
     {br.readLine();}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top