Ich möchte einen short-Wert im Little Endian-Format auf ein File ausgeben. Ich habe zwar ein Verfahren gefunden aber ich finde es ziemlich haarsträubend; sprich es gefällt mir nicht.
protected void methode() {
...
short wert=80;
byte[] bytes=shortToByteArray(wert);
StringBuffer littleEndian = new StringBuffer();
littleEndian.append(bytes[1]);
littleEndian.append(bytes[0]);
bufferedWriter.write(littleEndian.toString());
}
protected byte[] shortToByteArray(short a) {
byte[] ret = new byte[2];
ret[1] = (byte) (a & 0xFF);
ret[0] = (byte) ((a >> 8) & 0xFF);
return ret;
}
Das habe ich jetzt direkt in den Editor eingegeben; es kann also durchaus ein Tippfehler drin sein. Aber die Idee sollte deutlich werden.
Ich denke es sollte einen deutlich eleganteren Ansatz geben.
[QUOTE=Bleiglanz]Java ist nun mal Big Endian, was genau gefällt dir denn nicht?
Der StringBuffer ist natürlich käse, das muss schiefgehen: was soll das?[/QUOTE]
Wieso soll das schiefgehen - das Ganze funktioniert wunderbar. Sieht nur nicht schön aus. Und die Darstellung der Daten wird durch die Anwendung unter der sie benötigt werden bestimmt und nicht durch die Programmiersprache.
ShortBuffer shortBuffer = ByteBuffer.wrap(toWrite).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
// write shorts to shortBuffer
// write toWrite into Stream```[/QUOTE]
Danke für den Hinweis. Damit und mit der Javadoc bin ich jetzt zu dieser Löcung gekommen.
Wünschen würde ich mir einen OutputDatastream der das automatisch macht; schließlich ist LittleEndian durch Intel vermutlich mehr verbreitet als BigEndian.
Von Google gibt es das (com.google.common.io.LittleEndianDataOutputStream), wie ich jetzt gefunden habe. Aber ohne größere Not will ich die Klasse lieber nicht für den Classpath des Programms voraussetzen.
Jedenfalls danke nochmal; hat mir sehr geholfen.
das hat nichts mit besserwisserei zu tun , sondern einfach damit das man nun mal einfach keine „zeichen“ für rohe byte-werte nimmt
und das trifft auf Reader/Writer genau so zu wie eben auf einen String bzw dessen Buffer/Builder , weil dort intern mit einem char-array gearbeitet wird
und „-96“ sehen in einem char nun mal anders aus als in einem byte , womit du durch das casten die werte komplett durcheinander bringst
zusätzlich kann es zu problemen mit verschiedenen charsets kommen , weil java nun mal UTF-8 ist , viele daten unter windows aber gerne mal als ANSI oder WIN-1251 gespeichert werden , was dann zu wunderschönen fehlern führt bei denen man für die ursachenforschung mehr zeit braucht als es ein mal richtig zu lernen
[QUOTE=Unregistriert]das hat nichts mit besserwisserei zu tun , sondern einfach damit das man nun mal einfach keine “zeichen” für rohe byte-werte nimmt
und das trifft auf Reader/Writer genau so zu wie eben auf einen String bzw dessen Buffer/Builder , weil dort intern mit einem char-array gearbeitet wird
und “-96” sehen in einem char nun mal anders aus als in einem byte , womit du durch das casten die werte komplett durcheinander bringst
zusätzlich kann es zu problemen mit verschiedenen charsets kommen , weil java nun mal UTF-8 ist , viele daten unter windows aber gerne mal als ANSI oder WIN-1251 gespeichert werden , was dann zu wunderschönen fehlern führt bei denen man für die ursachenforschung mehr zeit braucht als es ein mal richtig zu lernen[/QUOTE]
Mein Einwurf war nicht so gemeint, dass ich die Bemerkung für falsch halte sondern für wenig hilfreich. Ich hatte eine relativ konkrete Frage nach Hilfestellung gestellt und als Antwort kommt ziemlich unspezifisch wie blöd die Angelegenheit doch sei.
Ich denke die Fragestellung ist auch nicht deutlich geworden. Ich wollte keine Zeichen darstellen sondern nur die Bytes im short umsortieren. Und dazu brauchte ich Zugriff auf diese Bytes.
Ob man die Zeichen jetzt mit ‘write(byte[])’ ausgibt oder sie über das casten nach char in einem String anordnet und dann mit ‘write(String)’ wegschreibt war für die Frage nicht so wichtig; ich hatte es nur aufgeführt um zu zeigen was ich vorhatte.
Codepages dienen der Abbildung der Bytes auf ein bestimmtes Zeichen. Aber das hat mich, wie gesagt, im vorliegenden Fall gar nicht interessiert. Ich wollte nur von BigEndian nach LittleEndian umschlüsseln.
Meine Lösung insgesamt sieht jetzt so aus:
{
...
DataOutputStream outStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(outputFile)));
short recordLength = getLittleEndian((short)record.length());
outStream.writeShort(recordLength);
outStream.writeChars(record);
...
}
public static short getLittleEndian(short value) {
ByteBuffer bb = ByteBuffer.allocateDirect(2);
ShortBuffer shortBuffer=bb.putShort(0, value).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
return shortBuffer.get();
}
Das Satzlängenfeld eines Satzes der Länge 80 (0x0050) wird damit als 0x5000 ins file geschrieben. Das hat auch vorher gut funktioniert; nur ist es jetzt über installierte Methoden erreicht worden.
[ot]Kann es sein, dass du LITTLE_ENDIAN mit BIG_ENDIAN verwechselst? Das ist keine Schande, zumindest nicht, solange es mir auch passiert(e)
0x0050 ist in LITTLE_ENDIAN „00 50“ (niederwertigste Byte steht hinten) und in BIG_ENDIAN „50 00“ (höchstwertigstes Byte steht hinten).[/ot]
Ansonsten… wie weit bist du mit dem umschreiben meines InputStreams? (Mach hinne, ich brauch’ den auch… :lol:)
[QUOTE=Spacerat]Bau dir doch einen… Ich hab’ das schon mal für 'nen InputStream gemacht, vllt. kannst den ja ummodeln.
…
[/QUOTE]
Herzliche Dank, kann ich gut gebrauchen werde ich für mich adaptieren.
[QUOTE=Spacerat][ot]Kann es sein, dass du LITTLE_ENDIAN mit BIG_ENDIAN verwechselst? Das ist keine Schande, zumindest nicht, solange es mir auch passiert(e)
0x0050 ist in LITTLE_ENDIAN „00 50“ (niederwertigste Byte steht hinten) und in BIG_ENDIAN „50 00“ (höchstwertigstes Byte steht hinten).[/ot]
Ansonsten… wie weit bist du mit dem umschreiben meines InputStreams? (Mach hinne, ich brauch’ den auch… :lol:)[/QUOTE]
Also ich bin ganz sicher hier nichts verwechselt zu haben. BigEndian entspricht unserer hexadezimalen Lesart; die Wertigkeit der Zahlen nimmt von links nach rechts ab und bei LittleEndian wird es byteweise genau andersherum geschrieben. vgl: Wikipedia
[QUOTE=JunkerJoerg]Also ich bin ganz sicher hier nichts verwechselt zu haben. BigEndian entspricht unserer hexadezimalen Lesart; die Wertigkeit der Zahlen nimmt von links nach rechts ab und bei LittleEndian wird es byteweise genau andersherum geschrieben. vgl: Wikipedia[/QUOTE]Ich sag’ doch, das ist keine Schande. :o