13293

Is there a less painful way to GetBytes for a buffer not starting at 0?

Question:

I am having to deal with raw bytes in a project and I need to basically do something like this

byte[] ToBytes(){ byte[] buffer=new byte[somelength]; byte[] tmp; tmp=BitConverter.GetBytes(SomeShort); buffer[0]=tmp[0]; buffer[1]=tmp[1]; tmp=BitConverter.GetBytes(SomeOtherShort); buffer[2]=tmp[0]; buffer[3]=tmp[1]; }

I feel like this is so wrong yet I can't find any better way of doing it. Is there an easier way?

Answer1:

BinaryWriter is very efficient:

byte[] ToBytes() { var ms = new MemoryStream(somelength); var bw = new BinaryWriter(ms); bw.Write(SomeShort); bw.Write(SomeOtherShort); return ms.ToArray(); }

Answer2:

You don't need to initialize tmp to a new array. BitConverter.GetBytes creates a new array and returns it for you. There's not much you can do about GetBytes but you can use methods like <a href="http://msdn.microsoft.com/en-us/library/system.buffer.blockcopy.aspx" rel="nofollow">Buffer.BlockCopy</a> to simplify the copy operation.

If you're not doing this in a performance-critical piece of code, you can go a bit LINQy and do things like:

IEnumerable<byte> bytes = BitConverter.GetBytes(first); bytes = bytes.Concat(BitConverter.GetBytes(second)); bytes = bytes.Concat(BitConverter.GetBytes(third)); // ... so on; you can chain the calls too return bytes.ToArray();

Answer3:

If you know the size beforehand (have a set of value types) you could use a struct and assign your values in the struct. Then use unsafe code to copy the raw bytes. I would still advise against it unless it's really necessary for speed purposes. And you might think it's painful :)

private struct MyStruct { public short A; public short B; public MyStruct(short a, short b) { A = a; B = b; } } private unsafe byte[] UnsafeStruct(MyStruct myStruct) { byte[] buffer = new byte[4]; // where 4 is the size of the struct fixed (byte* ptr = buffer) { *((MyStruct*)ptr) = myStruct; } return buffer; }

Answer4:

Just bit-shift...

buffer[0]=(byte)SomeShort; buffer[1]=(byte)(SomeShort >> 8); buffer[2]=(byte)SomeOtherShort; buffer[3]=(byte)(SomeOtherShort >> 8);

This also means you are in complete control of the endian-ness (in this case, little-endian)

Answer5:

You can make your code a little shorter by using Array.Copy, but no there isn't any GetBytes overload or equivalent in BitConverter that puts the bytes directly into your buffer.

Maybe <a href="http://msdn.microsoft.com/en-us/library/system.io.binarywriter.write.aspx" rel="nofollow">BinaryWriter</a> on a <a href="http://msdn.microsoft.com/en-us/library/system.io.memorystream.aspx" rel="nofollow">MemoryStream</a> is what you want?

Note that by adopting the API conventions of BitConverter which you don't like, you're causing the same problem for users of your class. Instead, write a method which accepts a BinaryWriter and serializes your class into it, this extends nicely when your class is embedded in some other object.

Recommend

  • Conflict between Log4Net's ThreadContext and Task
  • Difference between bytearray and list
  • How to render a full webpage in smaller iframe?
  • Where can I find the address of the Linux global mem_map array?
  • Is there a way to continuously pipe data from Azure Blob into BigQuery?
  • Generalizing from a specific type to a class in a GADT
  • Do not save model on duplicate file - Django 2
  • Get posts from all categories except one category
  • how to refresh alertdialog in flutter
  • Why UIWebView work so slowly when loadHTMLString with UIWebView?
  • Need to do a daily log rotation (0utc) using Python
  • Create and load data (objects)
  • How to display or get an image from Firebase storage
  • docker + nginx + node.js + php-fpm
  • Caching of Google Cloud Endpoints?
  • How to store model in `.pb` file with Estimator in TensorFlow?
  • GAE python NDB projection query working in development but not in production
  • How to set title name of the pdf. While viewing the Document(New Tab)
  • Tortoise SVN conflict occurs but no edit conflict button is shown
  • Alternative to bcrypt when saving passwords in PHP 5.2
  • get all files in git diff in intellij
  • How can I access the Google account user_id?
  • Anaconda + Apache + mod_wsgi + Ubuntu
  • Refresh JSF component after custom javascript Ajax call
  • Selenium Webdriver IE could not find element
  • Issue with Terrain Collision using Three.js
  • Checking for valid enum types from protobufs
  • How to output data of primefaces DataGrid component by columns instead of by rows (transpose data)?
  • Slice assignment to tensorflow variable
  • Year over Year Stats from a Crossfilter Dataset
  • Can I read another applications memory?
  • Floating parent div grows to hypothetical width of floating child div
  • Neo4j…how to get a visual representation of my data?
  • Stacked bar chart with continuous time-axis as x-axis
  • `$http:badreq Bad Request Configuration` - from angular post method, what is wrong here?
  • Firebase: How to read from external DB?
  • CAS 4 - Not able to retrieve the LDAP groups after successful authentication
  • JavaScript RegExp Replace