将 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();
}
}
}
我一直在尝试将以下 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();
}
}
}