2009-07-03 9 views
61

Ich habe eine Datei im .gz-Format. Die Java-Klasse zum Lesen dieser Datei ist GZIPInputStream. Diese Klasse erweitert jedoch nicht die BufferedReader-Klasse von Java. Daher kann ich die Datei Zeile für Zeile nicht lesen. Ich brauche so etwas wie diesesGZIPInputStream Zeile für Zeile lesen

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

ich aber meine Klasse zu schaffen, die den Reader oder BufferedReader-Klasse von Java erweitert und verwenden GZIPInputStream als eine ihrer Variablen.

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

} 

Aber das funktioniert nicht, wenn ich

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

Kann jemand Rat, wie Sie vorgehen ..

+0

siehe diesen Link http://stackoverflow.com/q/6717165/779408. Eine Komprimierungs- und Dekomprimierungsmethode wird dort dargestellt. – breceivemail

+0

Für die Liebe zu allem, was gut und richtig ist in dieser Welt und für die Vernunft aller Entwickler, die sogar remote lohnenden Code schreiben ..... BEACHTEN SIE, ENCODIEREN ALS @ERICKSON PUNKTE AUS! Er ist die einzige Antwort, die darauf hinweist, dass ich weinen möchte. – James

Antwort

114

Der Grundaufbau von Dekorateure ist wie folgt:

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

Die zentrale Frage in diesem Snippet der Wert encoding ist. Dies ist die Zeichenkodierung des Textes in der Datei. Ist es "US-ASCII", "UTF-8", "SHIFT-JIS", "ISO-8859-9", & hellip ;? es gibt Hunderte von Möglichkeiten, und die richtige Wahl kann normalerweise nicht aus der Datei selbst bestimmt werden. Es muss über einen Out-of-Band-Kanal angegeben werden.

Zum Beispiel, vielleicht ist es die Plattform Standard. In einer vernetzten Umgebung ist dies jedoch äußerst fragil. Der Computer, der die Datei geschrieben hat, könnte sich in der benachbarten Zelle befinden, aber eine andere Standarddateikodierung haben.

meisten Netzwerkprotokolle verwenden, um einen Header oder andere Metadaten, um explizit die Zeichenkodierung zu beachten.

In diesem Fall ergibt sich aus der Dateierweiterung, dass der Inhalt ist XML. XML enthält zu diesem Zweck in der XML-Deklaration das Attribut "encoding". Außerdem sollte XML wirklich mit einem XML-Parser, nicht als Text, verarbeitet werden. Das Lesen von XML Zeile für Zeile scheint ein fragiler Spezialfall zu sein.

Fehler bei der expliziten Angabe der Kodierung against the second commandment.Verwenden Sie die Standardkodierung auf eigene Gefahr!

+1

Dank es hat funktioniert ... Es besteht jedoch keine Notwendigkeit für Leser Schritt ist .. können wir schreiben es auch als GZIPInputStream gzip = new GZIPInputStream (new Fileinputstream ("F: /gawiki-20090614-stub-meta-history.xml. gz ")); \t \t BufferedReader br = new BufferedReader (new Inputstreamreader (gzip)); –

+12

@KapilD Es macht mich traurig, dass du seinen Punkt bezüglich der Kodierung komplett verpasst hast ... wie dein Kommentar und das Beispiel in deinem Kommentar zeigen.Lese die Antwort von Erickson nochmal ... vielleicht 30 mal. – James

+0

Wie kennt der Befehl gzip die Codierung? Ich möchte eine Menge Dateien von vielen Linux/Unix-Servern aus der ganzen Welt lesen ... also möchte ich sicherstellen, dass ich das richtig mache ... Der Post erwähnt die Kodierung kann normalerweise nicht durch die Datei selbst bestimmt werden ... aber der gzip -d-Befehl scheint bei jeder Datei ohne separate Eingabe zu funktionieren ... (was ich jetzt benutze, aber umgehen möchte), also denke ich, wenn ich nur herausfinden kann, was gzip tut, um die Codierung zu verstehen, ich kann das Gleiche tun. Irgendwelche Gedanken/Vorschläge kann mir jemand in die richtige Richtung weisen? – glyphx

0

Was:

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

Ihre Antwort ist großartig. Kurz und prägnant. Die Antwort von Erickson ist jedoch detaillierter. –

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