Frage von Felix193, 49

[Java] Wie kann man Daten in 5 bit kodieren und in Datei speichern?

Hallo,

ich möchte gerne eine größere Datenmenge möglichst effizient in eine Datei speichern. Da ich keine 256 Zeichen (8 bit) brauche, habe ich mir überlegt, dass 32 (5 bit) auch vollkommen reichen. Dementsprechend möchte ich nun etwa einen String in ein halbes byte kodieren. Zuvor habe ich mich leider kaum mit bytes in Java beschäftigt. Eine Recherche hat mir leider auch nicht weiter geholfen. Aber ich hab selbstständig einen Anfang schonmal geschrieben.

private String text;
text = "beispiel";
char[] chars = text.toCharArray(); //einzelne Buchstaben in Array
for(int i = 0; i < chars.length; i++){
    byte byte = (byte)chars[i] //kodierung
}

Ich weiß nicht, wie ich die Kodierung von einem byte zu etwa 5 bits ändern kann. Vielleicht könnt ihr mir ja helfen. Fürs wieder Auslesen muss ich es umgekehrt machen, dafür bräuchte ich aber auch erst die Lösung...

Vielen Dank!

Antwort
von JohnSnow42, 22

Du könntest immer 8 Zeichen zusammen in 40 Byte-Blöcken speichern / auslesen. Diese 40 Byte musst du entsprechend splitten und recodieren.

Das ist sicher eine gute Übung, aber ich habe starke Zweifel, dass das irgendwie performant wird. Vor allem wenn du dich nicht wirklich wirklich gut auskennst. Ich würde da eher überlegen, ob du die Daten nicht komprimiert speichern solltest. Java hat auch eine nette ZIP-API: http://www.oracle.com/technetwork/articles/java/compress-1565076.html

Dein Ansatz spart konstant 37,5% (3/8). Wenn deine Daten gezipped ähnlich groß sind, wäre Zippen definitv zu überlegen. - Wenn es Daten sind, die zB auch in eine Datenbank zu packen wären, können das die gängigen System auch auch schon put of the box (sogar SQLite kann ja zB compressed storage.).

Antwort
von LeCux, 26

Mit Bitbanging und Shiften kannst Du das erreichen.

Zum einen solltest Du dann aber nicht die ASCII Werte für die Buchstaben nehmen sondern das auf 0..31 matchen.

Dann ein long mit 0 initialisieren:

long a = 0;

if byte > 32: HILFE (sanity check)

a = a & byte

a = a << 5

Ein long in Java hat 64 bit, also kannst Du nach 8 Zeichen die 40 Bits daraus wieder in Zeichen umwandeln und rausshiften.

Als ganz grobe Idee.

ABER: (G)ZipInputStream bzw. -Outputstream machen Platzsparen viel einfacher als das manuell.

Antwort
von RakonDark, 19

das beispiel wird dir da so nichts bringen ,

das ganze müsstest du mit BitOperatoren machen .


teil dein 8 BIT in low and high bits auf .

den low wert setzt du mit 0000 1111
den high bit mit 1111 0000

wobei ich rechts das 1 bit sehe also 1^2

und immer die reihenfolge beachten :) fals du das ganze hintreinander willst :)

somit kannst du also 2 informationsblöcke in 1 byte vereinen .
das auslesen geschieht dann auch wieder mit BitOperatoren .

AND ist glaub ich alles was du brauchst zum lesen .

zum schreiben die jeweilige maske erzeugen und mit OR verknüpfen .

du könntest auch mit bit verschieben arbeiten und alles bei LOW organsieren , das könnte schicker sein .

wenn du also 2 informationsblöcke in deinem 1 byte untergebracht hast, dann kannst du das beispiel nutzen um es in Zeichen umzuwandeln und es zu schreiben .

ich gehe hier von 4 bits aus , weil deine schicke beschreibung von etwa der hälfte so schön komisch klingt , etwa gibt es bei logik nicht .

Kommentar von RakonDark ,

übrigens lassen sich 32 werte in nur 4 bits halten ,

0 bis 31 , das 5te bit wäre ja eine 32 somit also ein wert von 0 bis 63

Kommentar von RakonDark ,

ups das unsinn lol

Kommentar von Felix193 ,

Vielen Dank für die Antwort. Bei mir haben 4 bit nur 16 Werte^^

Ich arbeite jedoch einfachheitshalber mit nur 4 bit, vielleicht reichen die ja auch für mein Projekt, das ist aber jetzt erstmal zweit Rangig...

Denn wichtiger ist mir der Lerneffekt und der korrekte Umgang mit Bytes :) Leider klappt's noch nicht ganz. Und zwar bereitet mir noch das zusammenfügen ein Problem.

if(f != 0){ //checkt ob der hintere Teil überarbeitet werden muss
byte tempByte = 0b00000000; //erster Wert
bytes[i] = (byte) ((bytePrevTemp & 0x0) | (tempByte & 0x0)); //Zusammenführung
}else {
bytes[i] = 0b00000000;
}

Leider meckert er beim Zusammenführen. Ich hab leider auch durch eine Rechereche nicht die Ursache gefunden...

Antwort
von Rums777, 30

1 byte = 8 bit

Das ist nicht veränderbar.
Es besteht natürlich die Möglichkeit nur 5 bits in einem Byte zu speichern, aber dann würden die nächsten 3 bit mit 0en aufgefüllt werden.

Antwort
von PerfectMuffin, 19

Die Antworten hier reichen schon, ich wollt' nur hinzufügen:

Bytes zerlegen macht Spaß!

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten