在C#中将字节数组转换为短整型数组

16

我正在读取一个文件,并希望能够将从文件中获取的字节数组转换为短整型数组。

我该如何处理?


21
您想将1个字节转换为1个短整型,还是将2个字节转换为1个短整型? - maxwellb
7个回答

67

使用Buffer.BlockCopy方法。

将短数组创建为字节数组长度的一半,并将字节数据复制进去:

short[] sdata = new short[(int)Math.Ceiling(data.Length / 2)];
Buffer.BlockCopy(data, 0, sdata, 0, data.Length);

这绝对是目前最快的方法。


1
我不配拥有这个解决方案,但它是我现在所需要的! - DaMachk
2
谢谢!非常好的回答,不过我需要稍微改一下代码:short[] sdata = new short[(int)Math.Ceiling(data.Length / 2.0)];。否则,我会得到以下错误提示:“对于下列方法或属性调用存在歧义:'Math.Ceiling(decimal)' 和 'Math.Ceiling(double)'。” - Hagbard

15

一种可能性是使用Enumerable.Select

byte[] bytes;
var shorts = bytes.Select(b => (short)b).ToArray();

另一种方法是使用 Array.ConvertAll

byte[] bytes;
var shorts = Array.ConvertAll(bytes, b => (short)b);

1
你之前的建议(在后来添加第二个建议之前)相当低效。 - Philippe Leybaert
1
另一个选项是 bytes.Cast<short>().ToArray(); - Joel Mueller
1
实际上,这会导致 InvalidCastException 异常。简而言之,这段代码隐式地将一个装箱的字节类型的变量拆箱为 short 类型,而这不是有效的拆箱操作。详情请参见:https://dev59.com/yHRB5IYBdhLWcg3w-8Ho. - jason
3
当我使用"var shorts[] = Array.ConvertAll(bytes, b => (short)b);"时,我得到的是每个字节转换为短整型,而不是每对字节被转换。 - user18443

6

「shorthard」是由两个字节组成的复合类型。如果您将所有的 shorts 写入文件时都当作真正的 shorts,那么这些转换就是错误的。您必须使用两个字节来获取真正的 short 值,可以类似这样:

short s = (short)(bytes[0] | (bytes[1] << 8))

1
这样不行。你必须像这样做才能让它工作: short s = (short)((bytes[0] << 8) | bytes[1]); - DaveN59
4
假设使用小端存储,这段代码的意思是:将bytes数组中的第0个元素与第1个元素左移8位后按位或运算得到的结果强制转换为short类型,并赋值给变量s。 - Indy9000

2
short value = BitConverter.ToInt16(bytes, index);

这个使用 index 作为 LSB,index+1 作为 MSB。有没有一个遵循 BigEndian 的,使用 index 作为 MSB? - Nazar
1
你有没有仔细阅读问题?它是关于byte[]转换为short[],而不是short。 - Kishan Vaishnav

1
我不知道,但我本来期望对这个问题采用另一种方法。当将一系列字节转换为一系列shorts时,我会像 @Peter 一样完成它。
short s = (short)(bytes[0] | (bytes[1] << 8))

或者

short s = (short)((bytes[0] << 8) | bytes[1])

根据文件中字节的大小端,结果可能会有所不同。但是OP没有提到他对shorts的使用或文件中shorts的定义。在他的情况下,将字节数组转换为short数组没有意义,因为它会占用两倍的内存,而且我怀疑在其他地方使用时是否需要将byte转换为short。

0
 short[] wordArray = Array.ConvertAll(byteArray, (b) => (short)b);

在我看来,这会将每个字节转换为一个short,这可能不是预期的结果,因为两个字节才能表示一个short;-) - Tobias Raphael Dieckmann

-2
byte[] bytes;
var shorts = bytes.Select(n => System.Convert.ToInt16(n)).ToArray();

这非常低效:为每个元素调用convert.ToInt16(),将其存储在临时列表中,然后将其复制到一个新数组中。 - Philippe Leybaert
是的,这样做效率不高。但我认为与强制转换相比更安全。 - Muad'Dib
比强制转换更安全?将字节转换为短整型的强制转换总是有效的。它永远不会抛出异常。 - Philippe Leybaert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接