2009-07-03 18 views
61

Ho un file in formato .gz. La classe java per leggere questo file è GZIPInputStream. Tuttavia, questa classe non estende la classe BufferedReader di java. Di conseguenza, non sono in grado di leggere il file riga per riga. Ho bisogno di qualcosa di simileGZIPInputStream lettura riga per riga

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

ho pensato di creare la mia classe che estende l'Reader o BufferedReader classe di java e l'uso GZIPInputStream come uno dei suoi variabile.

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

} 

Ma, questo non funziona quando uso

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

può consigliare qualcuno come procedere ..

+0

guardare questo collegamento http://stackoverflow.com/q/6717165/779408. Un metodo di compressione e decompressione è rappresentato lì. – breceivemail

+0

Per l'amore di tutto ciò che è buono e giusto in questo mondo e per la sanità di tutti gli sviluppatori che scrivono anche codice remotamente valido ..... SIAMO CONSAPEVOLI DI CODIFICARE COME @erickson PUNTI FUORI! È l'unica risposta che lo fa notare, il che mi fa venir voglia di piangere. – James

risposta

114

La configurazione di base di decoratori è come questo:

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

La questione chiave in questo frammento è il valore della encoding. Questa è la codifica del carattere del testo nel file. È "US-ASCII", "UTF-8", "SHIFT-JIS", "ISO-8859-9" e hellip ;? ci sono centinaia di possibilità e la scelta corretta di solito non può essere determinata dal file stesso. Deve essere specificato tramite un canale out-of-band.

Ad esempio, forse è l'impostazione predefinita della piattaforma. In un ambiente di rete, tuttavia, questo è estremamente fragile. La macchina che ha scritto il file potrebbe sedersi nel cubicolo vicino, ma avere una codifica di file predefinita diversa.

La maggior parte dei protocolli di rete utilizza un'intestazione o altri metadati per rilevare esplicitamente la codifica dei caratteri.

In questo caso, dall'estensione del file viene visualizzato che il contenuto è XML. XML include l'attributo "encoding" nella dichiarazione XML per questo scopo. Inoltre, XML dovrebbe essere elaborato con un parser XML, non come testo. Leggere XML riga per riga sembra un caso fragile e speciale.

La mancata specificazione esplicita della codifica è against the second commandment.Utilizza la codifica predefinita a tuo rischio e pericolo!

+1

grazie ha funzionato ... Tuttavia, non è necessario per il passo del lettore .. possiamo anche scrivere come GZIPInputStream gzip = nuovo GZIPInputStream (nuovo FileInputStream ("F: /gawiki-20090614-stub-meta-history.xml. gz ")); \t \t BufferedReader br = new BufferedReader (nuovo InputStreamReader (gzip)); –

+12

@KapilD mi rattrista il fatto che tu abbia completamente mancato il suo punto riguardo la codifica ... come mostrato dal tuo commento e dall'esempio nel tuo commento.Rileggere la risposta di erickson .... forse 30 volte. – James

+0

In che modo il comando gzip conosce la codifica? Voglio leggere un sacco di file da molti server linux/unix di tutto il mondo ... quindi voglio essere sicuro di farlo bene ... Il post dice che la codifica di solito non può essere determinata dal file stesso ... ma il comando gzip -d sembra funzionare su qualsiasi file senza input separato ... (è quello che uso ora ma voglio aggirare) quindi immagino se riesco a capire cosa gzip fa per conoscere la codifica, io può fare lo stesso Qualche idea/suggerimento può qualcuno indicarmi la giusta direzione? – glyphx

0

Che dire:

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

+0

La tua risposta è fantastica. Breve e conciso .. Tuttavia, la risposta di erickson è più dettagliata. –

3
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); 
Problemi correlati