<p>I'm trying to read binary data using C#. I have all the information about the layout of the data in the files I want to read. I'm able to read the data "chunk by chunk", i.e. getting the first 40 bytes of data converting it to a string, get the next 40 bytes.</p>

<p>Since there are at least three slightly different version of the data, I would like to read the data directly into a struct. It just feels so much more right than by reading it "line by line".</p>

<p><strong>I have tried the following approach but to no avail:</strong></p>

<pre><code>StructType aStruct;
int count = Marshal.SizeOf(typeof(StructType));
byte[] readBuffer = new byte[count];
BinaryReader reader = new BinaryReader(stream);
readBuffer = reader.ReadBytes(count);
GCHandle handle = GCHandle.Alloc(readBuffer, GCHandleType.Pinned);
aStruct = (StructType) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(StructType));
handle.Free();
</code></pre>

<p>The stream is an opened FileStream from which I have began to read from. I get an <code>AccessViolationExceptio</code>n when using <code>Marshal.PtrToStructure</code>.</p>

<p>The stream contains more information than I'm trying to read since I'm not interested in data at the end of the file.</p>

<p><strong>The struct is defined like:</strong></p>

<pre><code>[StructLayout(LayoutKind.Explicit)]
struct StructType
{
    [FieldOffset(0)]
    public string FileDate;
    [FieldOffset(8)]
    public string FileTime;
    [FieldOffset(16)]
    public int Id1;
    [FieldOffset(20)]
    public string Id2;
}
</code></pre>

<p>The examples code is changed from original to make this question shorter.</p>

<p>How would I read binary data from a file into a struct?</p>

[{'answer_id': 2436, 'author': 'urini', 'author_id': 373, 'author_profile': 'https://Stackoverflow.com/users/373', 'pm_score': 0, 'selected': False, 'text': '<p>Try this:</p>\n\n<pre><code>using (FileStream stream = new FileStream(fileName, FileMode.Open))\n{\n    BinaryFormatter formatter = new BinaryFormatter();\n    StructType aStruct = (StructType)formatter.Deserialize(filestream);\n}\n</code></pre>\n'}, {'answer_id': 2474, 'author': 'lubos hasko', 'author_id': 275, 'author_profile': 'https://Stackoverflow.com/users/275', 'pm_score': 2, 'selected': False, 'text': "<p>I don't see any problem with your code.</p>\n\n<p>just out of my head, what if you try to do it manually? does it work?</p>\n\n<pre><code>BinaryReader reader = new BinaryReader(stream);\nStructType o = new StructType();\no.FileDate = Encoding.ASCII.GetString(reader.ReadBytes(8));\no.FileTime = Encoding.ASCII.GetString(reader.ReadBytes(8));\n...\n...\n...\n</code></pre>\n\n<p>also try</p>\n\n<pre><code>StructType o = new StructType();\nbyte[] buffer = new byte[Marshal.SizeOf(typeof(StructType))];\nGCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);\nMarshal.StructureToPtr(o, handle.AddrOfPinnedObject(), false);\nhandle.Free();\n</code></pre>\n\n<p>then use <strong>buffer[]</strong> in your BinaryReader instead of reading data from FileStream to see whether you still get AccessViolation exception.</p>\n\n<blockquote>\n  <p>I had no luck using the\n  BinaryFormatter, I guess I have to\n  have a complete struct that matches\n  the content of the file exactly.</p>\n</blockquote>\n\n<p>That makes sense, BinaryFormatter has its own data format, completely incompatible with yours.</p>\n"}, {'answer_id': 3200, 'author': 'Robert Höglund', 'author_id': 143, 'author_profile': 'https://Stackoverflow.com/users/143', 'pm_score': 2, 'selected': False, 'text': "<p>I had no luck using the BinaryFormatter, I guess I have to have a complete struct that matches the content of the file exactly. I realised that in the end I wasn't interested in very much of the file content anyway so I went with the solution of reading part of stream into a bytebuffer and then converting it using</p>\n\n<pre><code>Encoding.ASCII.GetString()\n</code></pre>\n\n<p>for strings and</p>\n\n<pre><code>BitConverter.ToInt32()\n</code></pre>\n\n<p>for the integers.</p>\n\n<p>I will need to be able to parse more of the file later on but for this version I got away with just a couple of lines of code.</p>\n"}, {'answer_id': 20803, 'author': 'Ishmaeel', 'author_id': 227, 'author_profile': 'https://Stackoverflow.com/users/227', 'pm_score': 5, 'selected': False, 'text': '<p>The problem is the <strong>string</strong>s in your struct. I found that marshaling types like byte/short/int is not a problem; but when you need to marshal into a complex type such as a string, you need your struct to explicitly mimic an unmanaged type. You can do this with the MarshalAs attrib.</p>\n\n<p>For your example, the following should work:</p>\n\n<pre><code>[StructLayout(LayoutKind.Explicit)]\nstruct StructType\n{\n    [FieldOffset(0)]\n    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]\n    public string FileDate;\n\n    [FieldOffset(8)]\n    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]\n    public string FileTime;\n\n    [FieldOffset(16)]\n    public int Id1;\n\n    [FieldOffset(20)]\n    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 66)] //Or however long Id2 is.\n    public string Id2;\n}\n</code></pre>\n'}, {'answer_id': 124089, 'author': 'Ronnie', 'author_id': 193, 'author_profile': 'https://Stackoverflow.com/users/193', 'pm_score': 0, 'selected': False, 'text': '<p>Reading straight into structs is evil - many a C program has fallen over because of different byte orderings, different compiler implementations of fields, packing, word size.......</p>\n\n<p>You are best of serialising and deserialising byte by byte. Use the build in stuff if you want or just get used to BinaryReader.</p>\n'}, {'answer_id': 2777781, 'author': 'nevelis', 'author_id': 333988, 'author_profile': 'https://Stackoverflow.com/users/333988', 'pm_score': 3, 'selected': False, 'text': '<p>As Ronnie said, I\'d use BinaryReader and read each field individually.  I can\'t find the link to the article with this info, but it\'s been observed that using BinaryReader to read each individual field can be faster than Marshal.PtrToStruct, if the struct contains less than 30-40 or so fields.  I\'ll post the link to the article when I find it.</p>\n\n<p>The article\'s link is at: <a href="http://www.codeproject.com/Articles/10750/Fast-Binary-File-Reading-with-C" rel="nofollow noreferrer">http://www.codeproject.com/Articles/10750/Fast-Binary-File-Reading-with-C</a></p>\n\n<p>When marshaling an array of structs, PtrToStruct gains the upper-hand more quickly, because you can think of the field count as fields * array length.</p>\n'}, {'answer_id': 4074557, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 4, 'selected': False, 'text': "<p>Here is what I am using.<br>This worked successfully for me for reading Portable Executable Format.<br>It's a generic function, so <strong><code>T</code></strong> is your <code>struct</code> type.</p>\n\n<pre><code>public static T ByteToType&lt;T&gt;(BinaryReader reader)\n{\n    byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));\n\n    GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);\n    T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));\n    handle.Free();\n\n    return theStructure;\n}\n</code></pre>\n"}, {'answer_id': 71456824, 'author': 'ssamko', 'author_id': 6158341, 'author_profile': 'https://Stackoverflow.com/users/6158341', 'pm_score': 0, 'selected': False, 'text': '<p>I had structure:</p>\n<pre><code>[StructLayout(LayoutKind.Explicit, Size = 21)]\n    public struct RecordStruct\n    {\n        [FieldOffset(0)]\n        public double Var1;\n\n        [FieldOffset(8)]\n        public byte var2\n\n        [FieldOffset(9)]\n        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]\n        public string String1;\n    }\n}\n</code></pre>\n<p>and I received <strong>&quot;incorrectly aligned or overlapped by non-object&quot;</strong>.\nBased on that I found:\n<a href="https://social.msdn.microsoft.com/Forums/vstudio/en-US/2f9ffce5-4c64-4ea7-a994-06b372b28c39/strange-issue-with-layoutkindexplicit?forum=clr" rel="nofollow noreferrer">https://social.msdn.microsoft.com/Forums/vstudio/en-US/2f9ffce5-4c64-4ea7-a994-06b372b28c39/strange-issue-with-layoutkindexplicit?forum=clr</a></p>\n<blockquote>\n<p>OK.  I think I understand what\'s going on here.  It seems like the\nproblem is related to the fact that the array type (which is an object\ntype) must be stored at a 4-byte boundary in memory.  However, what\nyou\'re really trying to do is serialize the 6 bytes separately.</p>\n<p>I think the problem is the mix between FieldOffset and serialization\nrules.  I\'m thinking that structlayout.sequential may work for you,\nsince it doesn\'t actually modify the in-memory representation of the\nstructure.  I think FieldOffset is actually modifying the in-memory\nlayout of the type.  This causes problems because the .NET framework\nrequires object references to be aligned on appropriate boundaries (it\nseems).</p>\n</blockquote>\n<p>So my struct was defined as explicit with:</p>\n<pre><code>[StructLayout(LayoutKind.Explicit, Size = 21)]\n</code></pre>\n<p>and thus my fields had specified</p>\n<pre><code>[FieldOffset(&lt;offset_number&gt;)]\n</code></pre>\n<p>but when you change your struct to Sequentional, you can get rid of those offsets and the error will disappear. Something like:</p>\n<pre><code>[StructLayout(LayoutKind.Sequential, Size = 21)]\n    public struct RecordStruct\n    {\n        public double Var1;\n\n        public byte var2;\n\n        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]\n        public string String1;\n    }\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/2384', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/143/']