Большим преимуществом слоя istream является обеспечение базового форматирования и анализа для простых типов ro и из потока. Для целей, которые вы описываете, ничего из этого не является действительно важным, и вы просто интересуетесь файлом как поток байтов.
Для этих целей вам лучше всего использовать интерфейс basic_streambuf, предоставляемый filebuf. Поведение «пропуска пробелов» является частью функциональности интерфейса istream, которая вам просто не нужна.
filebuf лежит в основе ifstream, но вполне допустимо использовать его напрямую.
std::filebuf myfile;
myfile.open( "myfile.dat", std::ios_base::in | std::ios_base::binary );
// gets next char, then moves 'get' pointer to next char in the file
int ch = myfile.sbumpc();
// get (up to) the next n chars from the stream
std::streamsize getcount = myfile.sgetn( char_array, n );
Также обратите внимание на функции snextc (перемещает указатель 'get' вперед и затем возвращает текущий символ), sgetc (получает текущий символ, но не перемещает указатель 'get') и sungetc (выполняет резервное копирование указатель 'get' на одну позицию, если это возможно).
Когда вам не нужны какие-либо операторы вставки и извлечения, предоставляемые классом istream, и вам просто нужен базовый байтовый интерфейс, часто интерфейс streambuf (filebuf, stringbuf) более подходит, чем интерфейс istream (ifstream, istringstream) .