XML-Daten komprimieren

Angel4585

Bekanntes Mitglied
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:
Java:
    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();
        }
    }
 
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.
 
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:
Java:
            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:
Java:
    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?
 
bytes zu String und zurück ist schon schlimm genug
Java:
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
Code:
[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..
 
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?
 

Neue Themen


Zurück
Oben