Метода bitconverter для Java

следуя рекомендациям, приведенным в вопросе https://stackoverflow.com/questions/1738244/what-is-the-java-equivalent-of-net-bitconverter я начал реализовывать свой собственный bitconverter для Java, но не получаю эквивалентных результатов.

может кто-нибудь, пожалуйста, направьте меня на то, что я могу делать неправильно?

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]

4 ответов


Это просто endianness (-46 и 210 из-за подписанных байтов Java, но это просто вещь пользовательского интерфейса). Либо отмените содержимое массива, либо используйте операции shift для записи int.

Примечание: endianness, что .NET испускает зависит от платформы. Я бы предложил использовать известную ЭНДИАННОСТЬ в обоих случаях; скорее всего, используя операции сдвига из обоих. Или, возможно, лучшая идея: просто используйте предварительно консервированный, независимый от платформы формат сериализации (например: буферы протокола, который имеет хорошую поддержку как на Java, так и на .NET / C#).

например, если я пишу int value до byte[] buffer (начиная с offset), я мог бы использовать:

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

это гарантируется little-endian, и аналогичный код должен работать на любой платформе.


C# BitConverter будет использовать endianness базовой achitecture. В большинстве случаев, это будет прямым порядком байтов (как в вашем случае). В Java DataOutputStream однако всегда будет писать в big-endian ("портативный способ"). Вам нужно будет проверить endianness машины и написать соответственно, если вы хотите соответствовать поведению.

кроме того, байты в java подписаны, поэтому вывод-это просто косметическая разница. Битовое представление такое же, поэтому вам не нужно беспокоиться об этом.

чтобы проверить endianness вашей машины, используйте java.nio.ByteOrder.nativeOrder() метод. Тогда используйте java.nio.ByteBuffer вместо этого, где вы можете указать байт order() и записи данных.

затем вы можете реализовать свой метод следующим образом:

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

основываясь на ответе Джеффа, вы можете использовать один ByteBuffer для преобразования как в и из int и byte[]. Вот код, который вы можете поместить в класс для преобразования в / из Little Endian:

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();
}

если любой потребности тела..C# для 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;
        }

Также Типа 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();
}