将 Java 的一段 ByteBuffer 代码翻译成 C#

Translating from Java to C# a snippet of ByteBuffer code

我一直在尝试将以下 Java 代码翻译成 C#。

    // two bytes to make a short (16 bit integer)
private short bytesToShort(byte hi, byte low) {
    return ByteBuffer.wrap(new byte[]{hi, low}).getShort();
}

到目前为止,这是我通过四处搜索设法组合起来的:

    private short bytesToShort(byte hi, byte low)
{
    MemoryStream stream = new MemoryStream();
    BinaryWriter writer = new BinaryWriter(stream);

    writer.Write(hi);
    writer.Flush();
    writer.Write(low);
    writer.Flush();

    BinaryReader reader = new BinaryReader(stream);
    
    return reader.ReadInt16();
    
}

但我收到 “无法读取超出流末尾的内容” 错误。在最后一个 writer.Flush(); 之后添加 stream.Position = 0; 修复了该问题,但我得到的值不正确。我想我对上面的代码有更多的问题并且 stream.Position = 0; 不是正确的答案,即使它似乎解决了这个问题。

有什么建议吗?

更新

我现在有两个可行的解决方案。第一个是 Andreas 在下面发布的答案:

return (short) (((hi & 0xFF) << 8) | (low & 0xFF));

它就像一个魅力,我认为在我拥有的两个解决方案中,这是更好的一个。 另一个是:

return BitConverter.ToInt16(new byte[2] { (byte)low, (byte)hi }, 0);

对于这个,我不得不交换“低”和“高”的位置以获得正确的结果。

重要! 对于那些从 Java 翻译成 C# 的人来说,Java 字节和 C# 字节之间有一个非常重要的区别。

Java 字节是有符号的,这意味着它取值介于 -128 到 127 之间,但 C# 字节是无符号的,取值介于 0 到 255 之间。

如果你想在 C# 中使用 Java 有符号字节,你必须使用 sbyte,这是我没有意识到的一个细节,它产生了问题对我来说。

return ByteBuffer.wrap(new byte[]{hi, low}).getShort() 等同于:

return (short) (((hi & 0xFF) << 8) | (low & 0xFF));

Java 和 C# 中的版本相同。

在 C# 中非常简单。您可以在 C#

中使用两种方法

首先是

short sh = (short)((hi << 4) | low);

其次,您可以使用 Convert.To 函数,如下所示

sh =Convert.ToInt16((hi << 4) | low);

这个转换功能非常强大,有很多选项。您还可以探索 BitConverter.ToInt16(byte[] array,int index)

下面是 C# 控制台应用程序的工作代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace testBitConvertor
{
    class Program
    {
        static void Main(string[] args)
        {
            byte hi = 1;
            byte low = 1;

            // short sh = BitConverter.ToInt16(new byte(hi << 8) | low),1);
            short sh = (short)((hi << 4) | low);
            Console.WriteLine(sh);
            sh =Convert.ToInt16((hi << 4) | low);
            Console.WriteLine(sh);
            Console.ReadKey();
        }
    }
}