适用于Java的Bitconverter

Max*_*ich 9 c# java primitive bytearray

按照问题/sf/ask/121677111/中提供的建议,我已经开始为Java实现我自己的bitconverter但是没有得到相同的结果.

有人可以指导我可能做错了吗?

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]
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 8

这只是字节序(-46和210是因为Java的签名字节,但这只是一个UI事物).要么反转数组内容,要么使用shift操作来编写int.

注意:.NET发出的字节顺序取决于平台.我建议在两种情况下使用KNOWN ENDIANNESS; 最有可能的方法是使用两者的轮班操作.或者更好的想法:只使用预先封装的,独立于平台的序列化格式(例如:协议缓冲区,它对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);
Run Code Online (Sandbox Code Playgroud)

这是保证little-endian,类似的代码应该适用于任何框架.


Jef*_*ado 5

C#BitConverter将使用底层架构的字节序。在大多数环境中,它将是小端字节序(就像您的情况一样)。然而, JavaDataOutputStream总是以大尾数法(“可移植方式”)编写。如果您想匹配行为,您需要检查机器的字节顺序并进行相应的写入。

另外,java 中的字节是有符号的,因此输出只是表面上的差异。位表示是相同的,因此您无需担心这一点。

要检查机器的字节顺序,请使用该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();
}
Run Code Online (Sandbox Code Playgroud)