# XML-Daten komprimieren



## Angel4585 (12. Nov 2010)

Hallo,

über diesen Code schieb ich ein Objekt mit einigen "Unterobjekten" in eine XML-Struktur die ich als String in ne Datenbank schreiben will. Da einige tausend dieser Strukturen in der Datenbank liegen werden, möchte ich die Daten komprimieren.

Wie kann ich die Daten komprimieren und später dekomprimieren?
Gibt es entweder ne Möglichkeit direkt bei der Datenbank direkt ein komprimiertes Feld zu machen, also dass die DB das komprimieren übernimmt? Oder gibts eine Java-Klasse mit der ich gut komprimieren und dekomprimieren kann?

Hier mal der Code:

```
public static SFMatch loadMatchFromStream(InputStream is) {
        XMLDecoder dec = null;
        try {
            dec = new XMLDecoder(is);
            return (SFMatch) dec.readObject();
        } finally {
            if (dec != null) {
                dec.close();
            }
        }
    }

    public static SFMatch loadMatchFromXMLString(String match) {
        ByteArrayInputStream bis = new ByteArrayInputStream(match.getBytes());
        return loadMatchFromStream(bis);
    }

    public static SFMatch loadMatchFromXMLFile(String filename) {
        try {
            return loadMatchFromStream(new FileInputStream(filename));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void saveMatchToStream(SFMatch match, OutputStream os) {
        XMLEncoder enc = null;
        try {
            enc = new XMLEncoder(os);
            enc.writeObject(match);
        } finally {
            if (enc != null) {
                enc.close();
            }
        }
    }

    public static String saveMatchToXMLString(SFMatch match) {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            saveMatchToStream(match, bos);
            String tmp = bos.toString();
            bos.close();
            return tmp;
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return "";
    }

    public static void saveMatchToXMLFile(SFMatch match, String filename) {
        try {
            FileOutputStream fos = new FileOutputStream(filename);
            saveMatchToStream(match, fos);
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
```


----------



## AlexSpritze (12. Nov 2010)

Mit dem Paket java.util.zip.* kannst du ohne extra Bibliothek Dateien in Java komprimieren. Vielleicht lässt sich das auch umbiegen, damit du nicht extra in Dateien sondern in Byte-Arrays schreibst.


----------



## Angel4585 (12. Nov 2010)

Danke! Die werd ich mal anschaun.


----------



## Angel4585 (12. Nov 2010)

So hab das mal eingebaut. Bei load- und save-MatchToXMLFile funktioniert das, ich kann die Datei auf der Festplatte auch entpacken und mir den Inhalt ansehen. Die Daten werden von 7KB auf 1KB komprimiert 

bei den load- und save-MatchToXMLString Methoden kommt mir aber beim laden folgende Meldung:
java.io.IOException: Not in GZIP format
        at java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:137)
        at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:58)
        at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:68)
        at b1.SFMatch.loadMatchFromXMLString(SFMatch.java:40)
        at sfloadsave.Main.main(Main.java:73)
der Aufruf:

```
SFMatch.saveMatchToXMLFile(match, "D:\\test.gz");
            SFMatch test1 = SFMatch.loadMatchFromXMLFile("D:\\test.gz");
            String strTest = SFMatch.saveMatchToXMLString(match);
            SFMatch test2 = SFMatch.loadMatchFromXMLString(strTest);
```
Die veränderten Methoden selbst:

```
public static String saveMatchToXMLString(SFMatch match) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        GZIPOutputStream gos = new GZIPOutputStream(bos);
        saveMatchToStream(match, gos);
        String tmp = bos.toString();
        gos.close();
        bos.close();
        return tmp;
    }

    public static SFMatch loadMatchFromXMLString(String match) throws IOException {
        ByteArrayInputStream bis = new ByteArrayInputStream(match.getBytes());
        GZIPInputStream gis = new GZIPInputStream(bis);
        SFMatch m = loadMatchFromStream(gis);
        gis.close();
        bis.close();
        return m;
    }
```

Am Rest hab ich nichts geändert. Ich selbst kann keinen Fehler entdecken,kann es vielleicht an sowas wie nem Zeichensatz vom ByteArrayStream liegen?


----------



## SlaterB (12. Nov 2010)

bytes zu String und zurück ist schon schlimm genug

```
public class Test {
    public static void main(String[] args)  {
        byte[] b =    {3, -50, 0, 111, -4};
        String st = new String(b);
        System.out.println(Arrays.toString(st.getBytes()));

        st = Base64.encode(b);
        System.out.println(Arrays.toString(Base64.decode(st)));
    }

}
```
Ausgabe

```
[3, -17, -65, -67, 0, 111, -17, -65, -67]
[3, -50, 0, 111, -4]
```

> import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
ob das mal Standard-API ist..


----------



## Angel4585 (12. Nov 2010)

ah ok,habs jetz in ein Byte Array gepackt und da gehts.
Mal schauen wie ich das sauber in die Datenbank bekomm. Ich denk mal ein binary blob oder sowas?


----------



## AlexSpritze (12. Nov 2010)

Angel4585 hat gesagt.:


> Ich denk mal ein binary blob oder sowas?



Ist bestimmt die beste Wahl.


----------

