title: Preferred way to parse a custom binary flat file?
body: <p>I have a flat file generated by a C program.  Each record in the file consists of a fixed length header followed by data.  The header contains a field indicating the size of the following data.  My ultimate goal is to write a C#/.NET program to query this flat file, so I'm looking for the most efficient way to read the file using C#.  </p>
  
  <p>I am having trouble finding the .NET equivalent of line 7 in the following code.  As far as I can tell, I have to issue multiple reads (one for each field of the header using BinaryReader) and then issue one read to get the data following the header.  I'm trying to learn a way to parse a record in two read operations (one read to get the fixed length header and a second read to get the following data).</p>
  
  <p>This is the C code I am trying to duplicate using C#/.NET:</p>
  
  <pre><code>struct header header; /* 1-byte aligned structure (48 bytes) */
  char *data;
  
  FILE* fp = fopen("flatfile", "r");
  while (!feof(fp))
  {
    fread(&amp;header, 48, 1, fp);
    /* Read header.length number of bytes to get the data. */
    data = (char*)malloc(header.length);
    fread(data, header.length, 1, fp);
    /* Do stuff... */
    free(data);
  }
  </code></pre>
  
  <p>This is C structure of the header:</p>
  
  <pre><code>struct header
  {
      char  id[2];
      char  toname[12];
      char  fromname[12];
      char  routeto[6];
      char  routefrom[6];
      char  flag1;
      char  flag2;
      char  flag3;
      char  flag4;
      char  cycl[4];
      unsigned short len;
  };
  </code></pre>
  
  <p>I've come up with this C# object to represent the C header:</p>
  
  <pre><code>[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi, Size = 48)]
  class RouterHeader
  {
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
      char[] Type;
  
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
      char[] To;
  
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
      char[] From;
  
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
      char[] RouteTo;
  
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
      char[] RouteFrom;
  
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
      char[] Flags;
  
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
      char[] Cycle;
  
      UInt16 Length;
  }
  </code></pre>