title: Reading binary files with null bytes in them with C++
body: <p>What is the canonical way to do this? </p>
  
  <p>I have to do the reading here into a <code>wstring</code>, but the answer i'm sure should be applicable to <code>string</code> also.</p>
  
  <p>Here's what I am trying now: </p>
  
  <pre><code>wifstream file(filename, ios::in | ios::binary);
  // this next line is cleverer but works the same way (i.e. null byte stops it)
  // return wstring(istreambuf_iterator&lt;wchar_t&gt;(file), istreambuf_iterator&lt;wchar_t&gt;());
  wstring out;
  wchar_t buf[8192];
  while (true) {
      file.read(buf, 8192);
      streamsize len = file.gcount();                                       
      cerr &lt;&lt; len &lt;&lt; "chars read.";                                         
      out.append(buf, len);                                                 
      if (len != 8192) break;                                               
  }                                                                         
  return out;
  </code></pre>
  
  <p>How can I get it to keep reading once it encounters a null byte in the file?</p>
  
  <p>I would actually not have been surprised if POSIX has a decree preventing null bytes from existing in any files ever. But clearly Vim is using some magic to write all those nulls into the undo-file format. Also, nulls must result if you happen to encode or encrypt stuff into a random byte-stream (or many kinds of analog sampling). I mean, I could keep going: the pipes (FIFOs) on OS X handle null bytes going through them just fine: I can cat the undofile, pipe it to xxd, it can read that.</p>
  
  <p>This is obviously some sort of simple thing I'm stumbling over. What is it? Surely there is a C++ way to do it. Or maybe you know a way with <code>&lt;stdio.h&gt;</code>. I want to know.</p>
  
  <p>For example, here's the file I'm testing with: </p>
  
  <pre><code>% cat .dmp.cpp.un\~| xxd | head                                   
  0000000: 5669 6d9f 556e 446f e500 0218 96c6 25f6  Vim.UnDo......%.
  0000010: 64bb 2301 6ed8 3578 5c50 61e0 eae5 a819  d.#.n.5x\Pa.....
  0000020: b17d 53b5 f932 dc9d 40aa 1b00 0000 8500  .}S..2..@.......
  0000030: 0000 5720 2020 2020 2020 2020 2020 2063  ..W            c
  0000040: 6572 7220 3c3c 2022 466f 756e 6420 616e  err &lt;&lt; "Found an
  0000050: 2075 6e70 7269 6e74 6162 6c65 2063 6861   unprintable cha
  </code></pre>
  
  <p>Byte 2b is the first nullbyte. Program reads 44 bytes (2c) so it wrote the first null byte, and stopped there.</p>
  
  <pre><code>% la .dmp.cpp.un\~
  -rw-r--r--  1 lust  staff  326836 Jul  4 01:41 .dmp.cpp.un~
  </code></pre>
  
  <p>P.S., I got that neat one-liner in the comment from <a href="http://www.gamedev.net/topic/353162-reading-a-whole-file-into-a-string-with-ifstream/" rel="nofollow">here</a>. Sadly it also suffers from this issue. </p>