# XML-Datei aus Zip-Datei auslesen, ohne temporär zu entpacken



## Daniel_L (1. Okt 2008)

Hallo,

folgendes Problem: Ich möchte mehrere XML-Dateien in einer Zip-Datei speichern und auch wieder laden. Dabei möchte ich, wenn es geht, die XML-Dateien _nicht_ vor dem "zippen" temporär auf Festplatte speichern - und umgekehrt, wenn ich die XML-Dateien aus dem Zip-Archiv einlese, möchte ich diese auch nicht temporär auf Platte speichern müssen.

Meine Frage: Geht das überhaupt? Wäre über Denkanstöße dankbar!

Gruß
Daniel


----------



## Gelöschtes Mitglied 5909 (1. Okt 2008)

klar geht das:

http://www.exampledepot.com/egs/java.util.zip/GetZip.html

und mit entry.getName() etc kannst du guggn ob du die richtige xml hast und gegebenenfals mit getNextEntry() dann eine "datei" in der zip überspringen

java.util.zip.ZipInputStream
int 	read(byte[] b, int off, int len)
        Reads from the *current* ZIP entry into an array of bytes.

und dann machst du da noch n InpuStreamReader außenrum und packst den dann in einen parser deiner wahl


----------



## Daniel_L (2. Okt 2008)

Wunderbar, vielen Dank! Dann mach ich mich mal ans ausprobieren...


----------



## Spacerat (2. Okt 2008)

Hallo...

Das erinnert mich an das OpenDocumentFormat von OpenOffice... Tolle Sache das... Gibt es dafür nicht auch schon einen Java-Reader?

mfg Spacerat


----------



## Wildcard (2. Okt 2008)

Es gibt die ODF Tools und natürlich kann man auch die UNO API verwenden um OpenOffice selbst von Java aus zu steuern.


----------



## Daniel_L (22. Okt 2008)

So, ich habe mal ausprobiert, aber so richtig will das nicht klappen. Vielleicht versteh ich die Funktionsweise von Input/Output-Streams auch nicht.

Mein aktueller Versuch sieht so aus:

```
try {
                ZipInputStream in = new ZipInputStream(new FileInputStream(fp));
                ZipEntry entry = in.getNextEntry();

                SAXBuilder builder = new SAXBuilder();
                Document doc = new Document();
                doc = builder.build(in);
                
                XMLOutputter out = new XMLOutputter(); 
                out.output( doc, System.out );
                in.close();
            }
            catch (IOException e) {
            
            }
```

An der Stelle "doc = builder.build(in)" springt er aus der try-Anweisung raus und zum Ende der Funktion (d.h. alles ab XMLOutputter wird nicht mehr ausgeführt, habe ich auch per Debugger getestet). Die Variable "fp" verweist auf eine zip-Datei. Wenn ich das von raiL gepostete Beispiel verwende, kann ich problemlos die in der ZIP-Datei enthaltene XML-Datei per OutputStream auf Festplatte speichern. Ich möchte ja aber gerne die Datei direkt, ohne "Umweg" über einen Datenträger, einlesen.

Kann mir da jemand weiterhelfen?

Vielen Dank und Gruß
Daniel


----------



## Wildcard (22. Okt 2008)

So nicht. Der InputStream ist gezippt, die Nutzdaten stehen im Entry.

```
catch (IOException e) {
           
            }
```
Mach sowas niemals. Das minimum ist ein e.printStackTrace, in einer fertigen Anwendung muss da logging rein.


----------



## Daniel_L (22. Okt 2008)

Gut, der fehlende Inhalt im catch-Bereich folgt noch. Aber zurück zu deiner Antwort: wie kann ich dann mit "entry" arbeiten? Das oben verlinkte Beispiel sieht folgendermaßen aus:

```
try {
        // Open the ZIP file
        String inFilename = "infile.zip";
        ZipInputStream in = new ZipInputStream(new FileInputStream(inFilename));
    
        // Get the first entry
        ZipEntry entry = in.getNextEntry();
    
        // Open the output file
        String outFilename = "o";
        OutputStream out = new FileOutputStream(outFilename);
    
        // Transfer bytes from the ZIP file to the output file
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
    
        // Close the streams
        out.close();
        in.close();
    } catch (IOException e) {
    }
```

Wenn ich "outFilename" in den Typ "File" ändere und einen Dateinamen vergebe, wird - obwohl die Variable "in" verwendet wird - die XML-Datei ausgelesen und auf Festplatte gespeichert. Im obigen Beispiel brauche ich "entry" also auch nicht verwenden. Außerdem verlangt der SAXBuilder ja nach einem InputStream. Hm...


----------



## Daniel_L (22. Okt 2008)

Kurzer Nachtrag: Außerdem müsste ich mindesten zwei try-Anweisungen verschachteln, oder? Eine für den ZipInputStream, und eine für den SAXBuilder...


----------



## Wildcard (22. Okt 2008)

... mein Fehler.

```
ZipInputStream in = new ZipInputStream(new FileInputStream(fp));
                ZipEntry entry = in.getNextEntry();

                SAXBuilder builder = new SAXBuilder();
                Document doc = new Document();
                doc = builder.build(in);
```
So war schon ok. Umso wichtiger ist eben die Ausgabe der Exception.


----------



## Daniel_L (22. Okt 2008)

Ok, der Code ist vom Ansatz her richtig, ja?

Hier die Fehlermeldung:


> com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 2 of 4-byte UTF-8 sequence.
> at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.invalidByte(UTF8Reader.java:674)
> at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read(UTF8Reader.java:463)
> at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1742)
> ...



Kann der Parser die in der ZIP-Datei enthaltene XML-Datei nicht lesen? Verstehe ich das richtig? Das ist jetzt eine, die ich auf die schnelle auf meiner Platte gefunden habe, und keine XML-Datei, mit mit dem SAXBuilder gespeichert wurde. Vielleicht sollte ich da was anderes ausprobieren?


----------



## Daniel_L (22. Okt 2008)

Ok, alles zurück!

 

Es lag tatsächlich an der XML-Datei. Habe eine andere versucht, und die wird korrekt ausgegeben... Auf sowas muss man kommen.


----------



## wurzeljunge (28. Aug 2009)

hi leute, 

ich hab genau das gleiche vor, jedoch mit einem passwortgeschützten .7z-archiv.

geht das? bzw. gibt es eine klasse, die das gleiche auch mit passwortgeschützten archiven kann?


----------

