Huffmann/Komprimierung

Status
Nicht offen für weitere Antworten.
T

Tanja

Gast
Hallo Leute,

Ich weiss nicht ob das hier richtig ist, aber ich bräuchte mal etwas Hilfestellung.

Ich habe ein beliebiges Objekt, welches ich über Netzwerk versenden will.
Da mein Gegenüber ebenfalls ein Objekt derselben Art mit gleichem Startzustand besitzt, sollte es ja reichen, wenn man den Unterschied der beiden Objekte überträgt. Ich weiss, es gibt den Begriff Deltakompression, aber mir sind da viele Sachen nicht klar:

Ich habe also mein Objekt. Was mache ich jetzt damit?
Ich will den Unterschied zwischen einer neuen und der alten Version einer Datei herausfinden, also müsste ich diese ja binär vergleichen. Aber wie mache ich das und wie speicher ich den Unterschied?

Wenn ich den Unterschied habe, sollte ich diesen ja komprimieren, um die Bandbreite zu schonen.
Wieder die selbe Frage, wie komprimiere ich binär?
Ich kenne Huffmann Codierung zwar Ansatzweise auf Buchstaben bezogen, aber das hilft mir irgendwie nicht.

Oder sollte man zuerst das neue und alte Objekt komprimieren, und dann den Unterschied extrahieren? Das dürfte doch nicht funktionieren, oder?

mmh. Ich wäre euch wirklich für jede Hilfe dankbar!

Liebe Grüße,
Tanja
 
T

Thorsten

Gast
Also, ich will dir mal kurz erklären, wie man Objekte binär schreibt (serialisieren) und diese auch
komprimiert:

Mit den ObjectInput und ObjectOutputStream kann man Objekte schreiben, die das Interface
Serializable implementieren. Mit eigenen Objekten (also von eigenen Klassen) geht das sehr
einfach. Du musst auch keine Methoden überladen wegen dem Interface.

Problem: Man kann nicht alle Objekte von den original Java Klassen schreiben. So kannst du alle
Swing und AWT Klassen schonmal vergessen!

Wenn du die normalen Streams, die du so oder so brauchst, in einen GZIP Input oder OutputStream
hängst, kannst du damit auch die Daten komprimieren. Also nur zwei Zeilen mehr Code!! :D

Hier ein bischen Code, der so aber nicht funktioniert. Muss man schon in einem richtigen
Kontext benutzen :wink:

Ich denke mal, dass du den Unterschied der Objekte nicht unbedingt erkennen können musst.
Mit diesen Code werden die Objekte so klein, dass du sie auch komplett übertragen kannst.
Es sei denn, es sind _richtig_ große Objekte...

Code:
01 import java.io.ObjectOutputStream;
02 import java.io.ObjectInputStream;
03 import java.io.BufferedInputStream;
04 import java.io.BufferedOutputStream;
05 import java.io.FileInputStream;
06 import java.io.FileOutputStream;
07 import java.util.zip.GZIPInputStream;
08 import java.util.zip.GZIPOutputStream;
09
10 //Schreiben von Objekten
11 try
12 {
13   FileOutputStream fos = new FileOutputStream(Filename);
14   BufferedOutputStream bos = new BufferedOutputStream(fos);
15   GZIPOutputStream gzip = new GZIPOutputStream(bos);
16   ObjectOutputStream oos = new ObjectOutputStream(gzip);
17  
18   oos.writeObject(myObject);
19  
20   gzip.finish();
21	
22   oos.close();
23   gzip.close();
24   bos.close();
25   fos.close();
26 }
27 catch (Exception e)
28 {
29   System.out.println("Error at writing...");
30   System.out.println(e.fillInStackTrace());
31 }
32
33 //Lesen von Objekten
34 try
35 {
36   FileInputStream fis = new FileInputStream(Filename);
37   BufferedInputStream bis = new BufferedInputStream(fis);
38   GZIPInputStream gzip = new GZIPInputStream(bis);
39   ObjectInputStream ois = new ObjectInputStream(gzip);
40	
41   myObject = (myObjectType) ois.readObject();
42						
43   ois.close();
44   gzip.close();
45   bis.close();
46   fis.close();
47 }
48 catch (Exception e)
49 {
50   System.out.println("Error at reading...");
51   System.out.println(e.fillInStackTrace());
52 }
 

meez

Top Contributor
Ich würde dir raten das Object trotzem zu versenden, und einfach alle Vars, welche nicht übertragen werden sollen, mit dem Schlüsselwort tranisent zu versehen. So werden diese bei einer Serialisierung nicht versendet...
Zudem kannst du es ja, wie oben beschrieben, noch komprimieren.
 
T

Tanja

Gast
Vielen Dank!

Das hilft mir wirklich weiter, ich hätte nicht gedacht das es sowas schon mehr oder weniger fertig gibt!

Die Objekte die ich packen will sind eigentlich nicht besonders groß, und haben mit Swing etc. nichts zu tun!

Danke nochmal, wenn ich wo nicht weiterkomme, melde ich mich nochmal :)
Muss das erstmal durcharbeiten.
 
T

Tanja

Gast
Hi, ich bins nochmal :)

Eines habe ich wohl noch nicht verstanden:
Ich möchte ja ein Objekt einlesen und packen, und keine Datei.

Dazu muss ich das Objekt doch erst einmal einlesen oder nicht?

Code:
ObjectInputStream ois = new ObjectInputStream(fis);

Der ObjectInputStream nimmt aber keine Objekte an, sondern nur den FileInputStream, mit dem ich ja nichts anfangen kann!

Was mache ich denn jetzt, oder habe ich einen Denkfehler?
Das Objekt wird ja intern im Programm schon erzeugt, und ändert sich ja auch ständig.

Was mache ich denn jetzt?
 
T

Thorsten

Gast
Nein, nein :wink:

Mein Code oben schreibt oder liest Objekte in / aus Dateien. Zunächst also immer
den FileInputStream oder FileOutputStream. Dem kann man einen Dateinamen
übergeben (als String).

Dann den BufferedInputStream oder BufferedOutputStream, um die Zugriffe
auf die Datei zu sammeln. Das beschleunigt den Zugriff etwas.

Danach eben den GZIP Stream, um die Daten zu packen, und ganz am
Ende erst den ObjectInput- oder ObjectOutputStream.

Der Object Stream nimmt natürlich keine Objekte :) Hast du dir meinen
Code oben nicht genau angesehen? :( Du musst dann nämlich von dem
ObjectStream Objekt die Methode writeObject() oder readObject() benutzen.

Statt die Objekte in eine Datei zu schreiben, oder sie dort auszulesen,
kannst du sie genau so einfach per Netzwerk über eine TCP/IP Verbindung
senden. Ich hab das jetzt aber nicht im Kopf, und hab auch meine Bücher
gerade nicht hier.... sorry. :(
 
T

Tanja

Gast
Das mit dem Netzwerk ist leider genau das Problem.
Da ich per UDP arbeite, kann ich keinen Stream senden.

Ich brauche eine Möglichkeit, ein einzelnes Objekt als Stream darstellen zu können, und auf diesen Stream muss ich dann bestimmte Operationen ausführen (Bitoperationen wie xor oder so) und diese dann komprimiert versenden.

Ich muss also ein Objekt "streamen", belibiege Operationen ausführen und dann diesen Stream packen und senden (als UDP Paket). Das einzige Problem was ich halt habe ist wie ich ein Objekt streame ohne über eine Datei zu gehen oder über Netzwerk :(
 
T

Thorsten

Gast
Tanja hat gesagt.:
Das einzige Problem was ich halt habe ist wie ich ein Objekt streame ohne über eine Datei zu gehen oder über Netzwerk :(

Die Antwort steht in diesem Buch:
http://www.amazon.de/exec/obidos/ASIN/3897212838/

Habs zuhause liegen, bin aber nun einige Tage nicht dort.
Mal sehen, ob ich dir morgen eine Antwort geben kann.
Ich hab da noch eine Notiz, und mit der Sun Dokumentation
kann ich dass eventuell rekonstruieren... mal sehen :wink:
 
T

Tanja

Gast
Vielen Dank für deine Arbeit!

Ich habe jetzt mal ein Objekt per byteArrayBufferStream oder so in ein byte-Array umgeleitet.
Ich habe momentan noch ein anderes kleines Problem, aber da bleib ich erstmal dran...

Werde morgen mal deinen Link bearbeiten ;)

bis denn!
 
T

Thorsten

Gast
Okay, nun deine gesuchte Lösung:

(Zitat aus dem Buch: "Java Kochbuch, ISBN: 3-89721-283-8", Seite 462 / 463)
Problem
Nachdem Sie verbunden sind, wollen Sie serialisierte Objektdaten übertragen.

Lösung
Konstruieren Sie einen ObjectInputStream oder ObjectOutputStream auf der
Grundlage der Methoden getInputStream() oder getOutputStream() des Sockets.

(Zitat Ende)

Alles klar? Hilft dir das nun? So kannst du also Objekte direkt per Netzwerk
versenden, ohne über eine Datei gehen zu müssen. Deine Klassse muss
allerdings das Interface Serializable implementieren :idea: Also die Klasse(n),
dessen Objekte versendet werden sollen...
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen


Oben