Метода 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();
}