# Objekte binär speichern



## jf (16. Aug 2010)

Hallo, ich möchte verschiedene Objekte mit großen Datenmengen binär speichern, da XML-Serialisierung zuviel Speicherplatz benötigt. Leider habe ich dies noch nicht gemacht, weshalb ich mich nun vertrauensvoll an die Leser dieses Forums wende. 

=> Wie sollte ich hierfür am Besten vorgehen?


----------



## KrokoDiehl (16. Aug 2010)

Suchst du so etwas?

```
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream	  objOut  = new ObjectOutputStream(byteOut);
objOut.writeObject(obj);
objOut.close();

byte[] data = byteOut.toByteArray();
```

Das schreibt ein Java-Objekt dass _Serializable_ implementiert in ein byte-Array. Es gibt sicher noch andere Varianten, aber diese habe ich g'rad gefunden


----------



## jf (16. Aug 2010)

Vielen Dank KrokoDiehl!
Wie schreibe ich das ByteArray in eine Datei? Mit FileWriter geht das scheinbar nicht...?


----------



## tuxedo (16. Aug 2010)

FileOutputStream z.B.


----------



## jf (16. Aug 2010)

tuxedo hat gesagt.:


> FileOutputStream z.B.


Ok, es läuft jetzt - doch leider ist die Ausgabe sogar noch größer, als die XML-Serialisierung... 

Kennt jemand eine Möglichkeit, wie man dies platzsparender hinbekommt?

Hintergrund:
Momentan werden die verschiedenen Datensätze in 32-Byte-Blöcke geschrieben.
Das Format ist natürlich für jede Art von Datensatz unterschiedlich, weshalb beim Schreiben, als auch beim Lesen eine separate Behandlung für jeden Datensatz-Typ erforderterlich ist. Dabei kennzeichnet das erste Byte jedes Blocks, um welche Art von Daten es sich handelt. Das Format ist sehr alt, z. B. werden aus historischen Gründen für das Datum (noch zweistellig!) sogar noch BCD-Werte verwendet.
Ich dachte mir nun, man könnte dies sehr viel effektiver gestalten, indem man ein Framework aus einer abstrakten Holder-Klasse und einer RecordSet-Klasse für jeden Datensatz-Typ (welche die abstrakte Klasse erweitert) erstellt. Die verschiedenen RecordSets können dabei sehr einfach serialisiert werden (mit ein paar wenigen Zeilen Quelltext können alle verschiedenen Datensatz-Typen geschrieben und auch gelesen werden).
Dies funktioniert auch wunderbar, doch wird leider sehr viel mehr Speicherplatz benötigt als zuvor mit dem binärem Blockformat. Da die Daten dann via Mobilfunk übermittelt werden sollen, ist dies ein großes Handycap. Über eure Ideen und Verbesserungsvorschläge wäre ich daher sehr dankbar!!! :applaus:


----------



## Gastredner (16. Aug 2010)

Wäre Zippen vielleicht eine Möglichkeit?
Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 14.10 Datenkompression


----------



## KrokoDiehl (16. Aug 2010)

Muss ggfs. nicht alles in den Objekten serialisiert werden? Mit 
	
	
	
	





```
transient
```
 kann man Eigenschaften angeben, die beim Serialisieren dann nicht mit gemacht werden. Vielleicht kannst du so auch auch Referenzen unter den Objekten untereinander lösen, die man dann ggfs nachträglich wieder einpflegen muss.
Ich bin in dem Thema aber auch nicht wirklich daheim... was ich meine ist:

```
class A
{ ... }

class B
{
   protected A myA;
}
```
Hier würde beim Serialisieren eines Objekts der Klasse _B_ das komplette Objekt _myA_ mit serialisiert. Wenn _myA_ aber zuvor schon serialisiert würde, könnte man sich das ggfs sparen.


----------



## jf (16. Aug 2010)

Danke für eure Anregungen.

Leider werden alle Klassenargumente benötigt, es gibt auch keine Verschachtelung von Objekten.

Das mit dem Zippen hatte ich auch als Notnagel im Kopf, lieber wäre mir allerdings ein Format, mit welcher man ein Objekt äußerst platzsparend in einer Datei speichern kann...


----------



## tuxedo (16. Aug 2010)

Wie Platzsparend muss es denn sein? Kommts da auf bytes oder kilobytes oder megabytes an?

Wenn nicht auf bytes ankommt: ObjectOutputStream ...

Ansonsten: Externalize benutzen ... google hilft.

- Alex


----------



## LoR (16. Aug 2010)

jf hat gesagt.:


> ... großen Datenmengen binär speichern ...



An deiner Stelle würde ich mir in einem solchen Fall eine eigenes binäres Format ausdenken. Dadurch hast du den gesamten Prozess unter Kontrolle und wirst bei halbwegs geschickten Vorgehen am meisten Platz sparen. Darüber hinaus kannst du auch abschätzen wieviel Speicherplatz du benötigen wird. Das Stichwort für das Thema lautet: *NIO* (z.B. JDK 1.4.2 New I/O-related APIs & Developer Guides -- from Sun Microsystems).


----------



## tuxedo (17. Aug 2010)

LoR hat gesagt.:


> An deiner Stelle würde ich mir in einem solchen Fall eine eigenes binäres Format ausdenken. Dadurch hast du den gesamten Prozess unter Kontrolle und wirst bei halbwegs geschickten Vorgehen am meisten Platz sparen. Darüber hinaus kannst du auch abschätzen wieviel Speicherplatz du benötigen wird. Das Stichwort für das Thema lautet: *NIO* (z.B. JDK 1.4.2 New I/O-related APIs & Developer Guides -- from Sun Microsystems).



Kommen wir nochmal aufs Thema zurück:



			
				jf hat gesagt.:
			
		

> ...ich möchte verschiedene Objekte mit großen Datenmengen binär speichern...



Also ich glaub' nicht, dass jf hier Objekte hat die so groß sind (das müssten ja fast schon gigabyte sein), dass sie das Speichern mit NIO erfordern um noch eine angemessene Performance zu bekommen. 

IO dürfte nach wie vor super ausreichend sein. Wenn das doch zu langsam ist, kann man immer noch auf NIO umbauen. Gab da doch ne Regel: Erst anfangen zu optimieren wenn man ein tatsächliches Problem hat. Alles andere führt zu nix 

Und zum Schluss: ObjectOutputStream wenns nicht auf bytes oder kilobytes ankommt, Externalize wenn's wirklich drauf ankommt einzelne bytes zu sparen.

- Alex


----------

