用于 Java 的位转换器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5865728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bitconverter for Java
提问by Maxim Gershkovich
Following the advice provided in the question https://stackoverflow.com/questions/1738244/what-is-the-java-equivalent-of-net-bitconverterI have begun implementing my own bitconverter for Java but am not getting equivalent results.
按照问题https://stackoverflow.com/questions/1738244/what-is-the-java-equivalent-of-net-bitconverter 中提供的建议,我已经开始为 Java 实现我自己的 bitconverter,但没有得到等效的结果。
Could someone please guide me on what I might be doing incorrectly?
有人可以指导我我可能做错了什么吗?
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]
采纳答案by Marc Gravell
That is just endianness (-46 and 210 is because of Java's signed bytes, but that is just a UI thing). Either reverse the array contents, or use shift operations to write the int.
这只是字节序(-46 和 210 是因为 Java 的有符号字节,但这只是 UI 的事情)。要么反转数组内容,要么使用移位操作写入 int。
Note: the endianness that .NET emits depends on the platform. I would suggest using KNOWN ENDIANNESS in both cases; most likely by using shift operations from both. Or perhaps a better idea: just use a pre-canned, platform independent serialization format (for example: protocol buffers, which has good support on both Java and .NET/C#).
注意:.NET 发出的字节顺序取决于平台。我建议在这两种情况下都使用 KNOWN Endianness ;最有可能通过使用两者的移位操作。或者也许是一个更好的主意:只需使用预制的、独立于平台的序列化格式(例如:协议缓冲区,它对 Java 和 .NET/C# 都有很好的支持)。
For example; if I was writing an int value
to a byte[] buffer
(starting at offset
), I might use:
例如; 如果我正在int value
向 a写信byte[] buffer
(从 开始offset
),我可能会使用:
buffer[offset++] = (byte)value;
buffer[offset++] = (byte)(value>>8);
buffer[offset++] = (byte)(value>>16);
buffer[offset++] = (byte)(value>>24);
this is guaranteed little-endian, and similar code should work on any framework.
这是保证小端的,类似的代码应该适用于任何框架。
回答by Jeff Mercado
The C# BitConverter
will use the endianness of the underlying achitecture. In most environments, it will be little-endian (as it is in your case). Java's DataOutputStream
however will always write in big-endian ("the portable way"). You'll need to check the endianness of the machine and write accordingly if you want to match the behavior.
C#BitConverter
将使用底层架构的字节序。在大多数环境中,它将是小端的(就像你的情况一样)。DataOutputStream
然而,Java将始终以大端(“可移植方式”)编写。如果您想匹配行为,您需要检查机器的字节顺序并相应地编写。
Also, bytes in java are signed so the output is just a cosmetic difference. The bit representation is the same so you don't need to worry about that.
此外,java 中的字节是有符号的,因此输出只是表面上的差异。位表示是相同的,因此您无需担心。
To check the endianness of your machine, use the java.nio.ByteOrder.nativeOrder()
method. Then use the java.nio.ByteBuffer
instead where you may specify the byte order()
and write the data.
要检查机器的字节顺序,请使用该java.nio.ByteOrder.nativeOrder()
方法。然后使用java.nio.ByteBuffer
代替您可以指定字节order()
并写入数据的地方。
You could then implement your method like this:
然后你可以像这样实现你的方法:
public static byte[] GetBytes(int value)
{
ByteBuffer buffer = ByteBuffer.allocate(4).order(ByteOrder.nativeOrder());
buffer.putInt(value);
return buffer.array();
}
回答by Jevgenij Kononov
if any body need..C# to JAVA BitConverter.ToInt32
如果任何机构需要..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;
}
Also Int16
还有 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
BitConverter.getBytes
public static byte[] GetBytesU16(long value)
{
ByteBuffer buffer = ByteBuffer.allocate(8).order(ByteOrder.nativeOrder());
buffer.putLong(value);
return buffer.array();
}
回答by Matt Klein
Building on Jeff's answer, you can use a single ByteBuffer
to convert both to and from int
and byte[]
. Here is code you can drop into a class to convert to/from Little Endian:
基于 Jeff 的回答,您可以使用 singleByteBuffer
来转换int
和byte[]
。以下是您可以放入类中以与 Little Endian 进行转换/从 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();
}