GZIPInputStream liest Zeile für Zeile

Lesezeit: 5 Minuten

Benutzer-Avatar
Kapil D

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. Dadurch kann ich die Datei nicht Zeile für Zeile lesen. Ich brauche so etwas

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

Ich dachte daran, meine Klasse zu erstellen, die die Klasse Reader oder BufferedReader von Java erweitert und GZIPInputStream als eine seiner Variablen verwendet.

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 es benutze

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

Kann jemand einen Rat geben, wie ich vorgehen soll..

  • Schauen Sie sich diesen Link an stackoverflow.com/q/6717165/779408. Dort ist ein Komprimierungs- und Dekomprimierungsverfahren dargestellt.

    – Bubi

    15. Januar 2013 um 10:41 Uhr

  • Aus Liebe zu allem, was in dieser Welt gut und richtig ist, und für die geistige Gesundheit aller Entwickler, die auch nur im Entferntesten lohnenden Code schreiben … BEACHTEN SIE DIE KODIERUNG, WIE @erickson HINWEIST! Er ist die einzige Antwort, die darauf hinweist, was mich zum Weinen bringt.

    – James

    7. Februar 2013 um 20:59 Uhr

Benutzer-Avatar
Erickson

Die grundlegende Einrichtung von Dekorateuren sieht folgendermaßen aus:

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

Das Schlüsselproblem in diesem Snippet ist der Wert von encoding. Dies ist die Zeichenkodierung des Textes in der Datei. Ist es „US-ASCII“, „UTF-8“, „SHIFT-JIS“, „ISO-8859-9“, …? Es gibt Hunderte von Möglichkeiten, und die richtige Wahl kann normalerweise nicht aus der Datei selbst ermittelt werden. Es muss über einen Außerbandkanal angegeben werden.

Vielleicht ist es zum Beispiel die Standardeinstellung der Plattform. In einer vernetzten Umgebung ist dies jedoch äußerst fragil. Die Maschine, die die Datei geschrieben hat, befindet sich möglicherweise in der benachbarten Kabine, hat aber eine andere Standarddateicodierung.

Die meisten Netzwerkprotokolle verwenden einen Header oder andere Metadaten, um die Zeichencodierung explizit zu vermerken.

In diesem Fall geht aus der Dateiendung hervor, dass es sich bei dem Inhalt um XML handelt. XML enthält zu diesem Zweck das Attribut “encoding” in der XML-Deklaration. Außerdem sollte XML wirklich mit einem XML-Parser verarbeitet werden, nicht als Text. Das zeilenweise Lesen von XML scheint ein fragiler Sonderfall zu sein.

Wenn die Codierung nicht explizit angegeben wird, ist gegen das zweite Gebot. Verwenden Sie die Standardcodierung auf eigene Gefahr!

  • danke, es hat funktioniert … Es ist jedoch kein Reader-Schritt erforderlich. Wir können es auch als GZIPInputStream schreiben. )); BufferedReader br = new BufferedReader(new InputStreamReader(gzip));

    – Kapil D

    4. Juli 2009 um 15:55 Uhr

  • @KapilD Es macht mich traurig, dass Sie seinen Standpunkt zur Codierung völlig verfehlt haben … wie Ihr Kommentar und das Beispiel in Ihrem Kommentar zeigen. Lesen Sie Ericksons Antwort erneut … vielleicht 30 Mal.

    – James

    7. Februar 2013 um 20:53 Uhr

  • Woher kennt der gzip-Befehl die Codierung? Ich möchte viele Dateien von vielen Linux/Unix-Servern aus der ganzen Welt lesen … also möchte ich sicherstellen, dass ich das richtig mache … Der Beitrag erwähnt, dass die Codierung normalerweise nicht durch die Datei selbst bestimmt werden kann … aber der Befehl gzip -d scheint bei jeder Datei ohne separate Eingabe zu funktionieren … (es ist das, was ich jetzt verwende, aber umgehen möchte), also denke ich, wenn ich nur herausfinden kann, was gzip tut, um die Codierung zu kennen, ich kann das gleiche tun. Irgendwelche Gedanken/Anregungen kann mir jemand in die richtige Richtung weisen?

    – glyphx

    18. Dezember 2013 um 15:45 Uhr


  • @glyphx Ihre Frage ist nicht klar. Meinen Sie, wie können Sie eine gzip-Datei erkennen, wenn keine externe Aussage über den Inhaltstyp vorliegt? Ein Hinweis ist die Dateiendung, ein anderer ist das Vorhandensein der magischen Zahl 0x1F8B im Dateiheader. Sie können jedoch nicht wissen, dass eine Datei eine gültige gzip-Datei ist, bis Sie das Ganze tatsächlich verarbeitet haben.

    – Ericsson

    18. Dezember 2013 um 18:48 Uhr

  • Um klar zu sein, ich weiß, dass diese Dateien gzip-Dateien sind. Und die gzippten Dateien sind alle textbasierte Dateien, wie CSV- und Pipe-Delim-Dateien. Ich möchte diese Dateien nur Zeile für Zeile direkt mit Java lesen können. Ich kann sie gzip -d und sie dann Zeile für Zeile lesen, kein Problem. Ich war nur verwirrt in Ihren Kommentaren darüber, dass Sie die Codierung angeben müssen … Ich würde denken, die meisten Dateien sind ASCII … aber einige könnten asiatische Zeichen haben, also vielleicht UTF-8? Ich möchte nur sicherstellen, dass ich das richtig mache … Ist das klarer? Vielen Dank!

    – glyphx

    20. Dezember 2013 um 20:47 Uhr

Benutzer-Avatar
ChssPly76

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

  • Ihre Antwort ist großartig. Kurz und prägnant. Ericksons Antwort ist jedoch ausführlicher.

    – Kapil D

    4. Juli 2009 um 15:54 Uhr

Benutzer-Avatar
Arumugam Mathiazhagan

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

Sie können die folgende Methode in einer util-Klasse verwenden und bei Bedarf verwenden …

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

Benutzer-Avatar
Dompteur

Hier ist mit einer Zeile

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

1257220cookie-checkGZIPInputStream liest Zeile für Zeile

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy