15

I'm currently reading a file and wanted to be able to convert the array of bytes obtained from the file into a short array.

How would I go about doing this?

William Troup
  • 12,739
  • 21
  • 70
  • 98

7 Answers7

66

Use Buffer.BlockCopy.

Create the short array at half the size of the byte array, and copy the byte data in:

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

It is the fastest method by far.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
steppenwolfe
  • 661
  • 1
  • 5
  • 2
  • 1
    The solution i don't deserve, but the one i need right now! – DaMachk Apr 16 '16 at 18:26
  • 2
    Thanks! Great answer but I had to change the code slightly to: short[] sdata = new short[(int)Math.Ceiling(data.Length / 2.0)];. Otherwise, I would have gotten the following error: "The call is ambiguous between the following methods or properties: 'Math.Ceiling(decimal)' and 'Math.Ceiling(double)' " – Hagbard Dec 19 '18 at 12:18
15

One possibility is using Enumerable.Select:

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

Another is to use Array.ConvertAll:

byte[] bytes;
var shorts = Array.ConvertAll(bytes, b => (short)b);
jason
  • 236,483
  • 35
  • 423
  • 525
  • 1
    Your original suggestion (before you added the second one later on) is rather inefficient – Philippe Leybaert Jul 09 '09 at 15:35
  • 1
    Another option would be bytes.Cast().ToArray(); – Joel Mueller Aug 09 '09 at 04:04
  • 1
    Actually, this results in a InvalidCastException. The short explanation is that this code implicitly causes an boxed byte to be unboxed to a short which is not a valid unboxing operation. For details, see http://stackoverflow.com/questions/445471/puzzling-enumerable-cast-invalidcastexception. – jason Aug 19 '09 at 06:56
  • 3
    When I used var shorts[] = Array.ConvertAll(bytes, b => (short)b); I got each byte converted to a short not each pair of bytes converted. –  Nov 29 '15 at 22:57
6

A shorthard is a compound of two bytes. If you are writing all the shorts to the file as true shorts then those conversions are wrong. You must use two bytes to get the true short value, using something like:

short s = (short)(bytes[0] | (bytes[1] << 8))
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 1
    This doesn't work. You have to do it like this to make it work: short s = (short)((bytes[0] << 8) | bytes[1]); – DaveN59 Dec 03 '09 at 21:12
  • 4
    Assuming little endian, this should be: short s = (short)(bytes[0] | (bytes[1] << 8)) – Indy9000 May 31 '11 at 16:45
2
short value = BitConverter.ToInt16(bytes, index);
Gabriel
  • 37
  • 1
1

I dont know, but I would have expected another aproach to this question. When converting a sequence of bytes into a sequence of shorts, i would have it done like @Peter did

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

or

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

depending on endianess of the bytes in the file.

But the OP didnt mention his usage of the shorts or the definition of the shorts in the file. In his case it would make no sense to convert the byte array to a short array, because it would take twice as much memory, and i doubt if a byte would be needed to be converted to a short when used elsewhere.

Wolfgang Roth
  • 451
  • 4
  • 18
0
 short[] wordArray = Array.ConvertAll(byteArray, (b) => (short)b);
Philippe Leybaert
  • 168,566
  • 31
  • 210
  • 223
-2
byte[] bytes;
var shorts = bytes.Select(n => System.Convert.ToInt16(n)).ToArray();
Jhonny D. Cano -Leftware-
  • 17,663
  • 14
  • 81
  • 103
Muad'Dib
  • 28,542
  • 5
  • 55
  • 68