3

I need to process a binary resource (contents of a binary file). The file contains shorts. I can't figure how to cast the result of accessing that resource to a short array though:

short[] indexTable = Properties.Resources.IndexTable;

doesn't work; I can only use

byte[] indexTable = Properties.Resources.IndexTable;

Using Array.Copy wouldn't work since it would convert each byte from the array returned by accessing the resource to a short.

How do I solve this problem please (other than manually converting the byte array)? Is there a way to tell C# that the resource is of type short[] rather than byte[]?

I had even tried to edit the project's resx file and change the resources' data types to System.UInt16, but then I got the error message that now constructor could be found for them.

Using VS 2010 Express and .NET 4.0.

Justin Ethier
  • 131,333
  • 52
  • 229
  • 284
Razzupaltuff
  • 2,250
  • 2
  • 21
  • 37
  • 1
    Binary files contain bytes, not shorts. A short is a system specific structure which bytes may be interpreted as, same as bytes can be interpreted as text, pictures, or anything else you see on a computer. – Jimmy Hoffa Aug 27 '10 at 17:32
  • Why not just use a byte array?? Like @Jimmy Hoffa said the files contains bytes. – Gage Aug 27 '10 at 17:44
  • Jimmy, of course these files contain bytes. I want its contents to be interpreted as ushort though, and that means I somehow need to get it into an ushort array. – Razzupaltuff Aug 27 '10 at 18:55
  • possible duplicate of [Directly reading large binary file in C# w/out copying](http://stackoverflow.com/questions/3206391/directly-reading-large-binary-file-in-c-w-out-copying) – Ben Voigt Aug 27 '10 at 19:54

3 Answers3

4

You should use BinaryReader:

using (var reader = new BinaryReader(new MemoryStream(Properties.Resources.IndexTable)))
{
    var firstValue = reader.ReadInt16();
    ...
}
Kirk Woll
  • 76,112
  • 22
  • 180
  • 195
  • +1, I was thinking BitConverter, not used to using BinaryReader, I always just push bytes around with the base stream. I should try to remember there's a binaryreader next time.. – Jimmy Hoffa Aug 27 '10 at 17:33
  • I had hoped I'd be able to get around having to read the array element wise, but this is a good way to read the data they way I want. – Razzupaltuff Aug 27 '10 at 18:57
  • I had to think a while about your and Joel Rondeau's propositions, and in the end went for yours because it is the most flexible one and easily allows to read arbitrarily structured data from resources. Thank you. – Razzupaltuff Aug 27 '10 at 19:29
  • BitConverter would be MUCH faster than BinaryReader. – Ben Voigt Aug 27 '10 at 19:54
  • Wouldn't I still have to read the resource before converting it using BitConverter? – Razzupaltuff Aug 31 '10 at 23:47
4

Buffer.BlockCopy()

byte[] srcTable = Properties.Resources.IndexTable;
short[] destTable = new short[srcTable.Length / 2];
Buffer.BlockCopy(srcTable, 0, destTable, 0, srcTable.Length);
Joel Rondeau
  • 7,486
  • 2
  • 42
  • 54
0

Here's how if you prefer a 'Do it yourself' style (however, I personally prefer @Joel Rondeau's method)

byte[] bytes = Properties.Resources.IndexTable;
short[] shorts = new short[bytes.Length/2];

for( int i = 0; i < bytes.Length; i += 2 )
{
    // the order of these depends on your endianess
    // big
    shorts[i/2] = (short)(( bytes[i] << 8 ) | (bytes[i+1] )); 
    // little
    // shorts[i/2] = (short)(( bytes[i+1] << 8 ) | (bytes[i] )); 
}
µBio
  • 10,668
  • 6
  • 38
  • 56