10 Stimmen

Bitkonverter für Java

Befolgen Sie die in der Frage enthaltenen Ratschläge https://stackoverflow.com/questions/1738244/what-is-the-java-equivalent-of-net-bitconverter Ich habe begonnen, meinen eigenen Bitkonverter für Java zu implementieren, aber ich erhalte keine gleichwertigen Ergebnisse.

Könnte mir bitte jemand sagen, was ich falsch machen könnte?

public static byte[] GetBytes(Integer value) {
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    DataOutputStream stream = new DataOutputStream(byteStream);
    try {
        stream.writeInt(value);
    } catch (IOException e) {
        return new byte[4];
    }
    return byteStream.toByteArray();
}

byte[] result = BitConverter.GetBytes(1234); //JAVA: [0, 0, 4, -46]
byte[] result = BitConverter.GetBytes(1234); //C#: [210, 4, 0, 0]

11voto

Marc Gravell Punkte 970173

Das ist nur Endianness (-46 und 210 ist wegen Java's signierten Bytes, aber das ist nur eine UI Sache). Entweder kehren Sie den Array-Inhalt um, oder verwenden Sie Shift-Operationen, um den int zu schreiben.

Hinweis: Die Endianness, die .NET ausgibt, hängt von der Plattform ab. Ich würde vorschlagen, KNOWN ENDIANNESS in beiden Fällen zu verwenden; höchstwahrscheinlich durch die Verwendung von Shift-Operationen von beiden. Oder vielleicht eine bessere Idee: verwenden Sie einfach ein vorgefertigtes, plattformunabhängiges Serialisierungsformat (zum Beispiel: Protokollpuffer, die gute Unterstützung auf Java und .NET/C# hat).

Zum Beispiel: Wenn ich eine int value zu einer byte[] buffer (beginnend bei offset ), könnte ich verwenden:

buffer[offset++] = (byte)value;
buffer[offset++] = (byte)(value>>8);
buffer[offset++] = (byte)(value>>16);
buffer[offset++] = (byte)(value>>24);

Dies ist garantiert Little-Endian, und ähnlicher Code sollte auf jedem Framework funktionieren.

5voto

Jeff Mercado Punkte 120818

Die C# BitConverter verwendet die Endianness der zugrunde liegenden Architektur. In den meisten Umgebungen wird es Little-Endian sein (wie in Ihrem Fall). Javas DataOutputStream wird jedoch immer in Big-Endian geschrieben ("the portable way"). Sie müssen die Endianness der Maschine überprüfen und entsprechend schreiben, wenn Sie das Verhalten anpassen wollen.

Außerdem sind Bytes in Java vorzeichenbehaftet, so dass die Ausgabe nur ein kosmetischer Unterschied ist. Die Bit-Darstellung ist die gleiche, so dass Sie nicht darüber nachdenken müssen.

Um die Endianness Ihres Rechners zu überprüfen, verwenden Sie die java.nio.ByteOrder.nativeOrder() Methode. Verwenden Sie dann die java.nio.ByteBuffer wo Sie stattdessen das Byte angeben können order() und schreiben die Daten.

Sie könnten Ihre Methode dann wie folgt implementieren:

public static byte[] GetBytes(int value)
{
    ByteBuffer buffer = ByteBuffer.allocate(4).order(ByteOrder.nativeOrder());
    buffer.putInt(value);
    return buffer.array();
}

4voto

Jevgenij Kononov Punkte 1002

Wenn jemand brauchen..C# zu JAVA BitConverter.ToInt32

  public static int toInt32_2(byte[] bytes, int index)
        {
            int a = (int)((int)(0xff & bytes[index]) << 32 | (int)(0xff & bytes[index + 1]) << 40 | (int)(0xff & bytes[index + 2]) << 48 | (int)(0xff & bytes[index + 3]) << 56);
            // int a = (int)((int)(0xff & bytes[index]) << 56 | (int)(0xff & bytes[index + 1]) << 48 | (int)(0xff & bytes[index + 2]) << 40 | (int)(0xff & bytes[index + 3]) << 32);
            //Array.Resize;
            return a;
        }

Auch Int16

    public static short toInt16(byte[] bytes, int index) //throws Exception
    {
        return (short)((bytes[index + 1] & 0xFF) | ((bytes[index] & 0xFF) << 0));
        //return (short)(
        //        (0xff & bytes[index]) << 8 |
        //                (0xff & bytes[index + 1]) << 0
        //);
    }

BitConverter.getBytes

public static byte[] GetBytesU16(long value)
{

    ByteBuffer buffer = ByteBuffer.allocate(8).order(ByteOrder.nativeOrder());
    buffer.putLong(value);
    return buffer.array();
}

1voto

Matt Klein Punkte 7076

Aufbauend auf Jeffs Antwort, können Sie eine einzelne ByteBuffer zur Konvertierung von und nach int y byte[] . Hier ist Code, den Sie in eine Klasse einfügen können, um nach/von Little Endian zu konvertieren:

ByteBuffer _intShifter = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE)
                                   .order(ByteOrder.LITTLE_ENDIAN);

public byte[] intToByte(int value) {
    _intShifter.clear();
    _intShifter.putInt(value);      
    return _intShifter.array();
}

public int byteToInt(byte[] data)
{
    _intShifter.clear();
    _intShifter.put(data, 0, Integer.SIZE / Byte.SIZE);
    _intShifter.flip();
    return _intShifter.getInt();
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X