Read files in binary mode to simplify implementation

- adds null detection special case
- handles empty file edge case
- works entirely in binary mode
- avoids depending on six for Python 2/3 compatibility