× {{alert.msg}} Never ask again
Get notified about new tutorials RECEIVE NEW TUTORIALS

Parsing a binary file. What is a modern way?

Arnaud Bellec
Jun 12, 2015
<p>The C way, which would work fine in C++, would be to declare a struct:</p> <pre><code>#pragma pack(1) struct contents { // data members; }; </code></pre> <p>Note that</p> <ul> <li>You need to use a pragma to make the compiler align the data <em>as-it-looks</em> in the struct;</li> <li>This technique only works with <a href="http://stackoverflow.com/questions/146452/what-are-pod-types-in-c">POD types</a></li> </ul> <p>And then cast the read buffer directly into the struct type:</p> <pre><code>std::vector&lt;char&gt; buf(sizeof(contents)); file.read(buf.data(), buf.size()); contents *stuff = reinterpret_cast&lt;contents *&gt;(buf.data()); </code></pre> <p>Now if your data's size is variable, you can separate in several chunks. To read a single binary object from the buffer, a reader function comes handy:</p> <pre><code>template&lt;typename T&gt; const char *read_object(const char *buffer, T&amp; target) { target = *reinterpret_cast&lt;const T*&gt;(buffer); return buffer + sizeof(T); } </code></pre> <p>The main advantage is that such a reader can be specialized for more advanced c++ objects:</p> <pre><code>template&lt;typename CT&gt; const char *read_object(const char *buffer, std::vector&lt;CT&gt;&amp; target) { size_t size = target.size(); CT const *buf_start = reinterpret_cast&lt;const CT*&gt;(buffer); std::copy(buf_start, buf_start + size, target.begin()); return buffer + size * sizeof(CT); } </code></pre> <p>And now in your main parser:</p> <pre><code>int n_floats; iter = read_object(iter, n_floats); std::vector&lt;float&gt; my_floats(n_floats); iter = read_object(iter, my_floats); </code></pre> <p><strong>Note:</strong> As Tony D observed, even if you can get the alignment right via <code>#pragma</code> directives and manual padding (if needed), you may still encounter incompatibility with your processor's alignment, in the form of (best case) performance issues or (worst case) trap signals. This method is probably interesting only if you have control over the file's format.</p> <p>This tip was originally posted on <a href="http://stackoverflow.com/questions/26845538/Parsing%20a%20binary%20file.%20What%20is%20a%20modern%20way?/26845612">Stack Overflow</a>.</p>
comments powered by Disqus