Чтение двоичного файла istream byte byte - PullRequest
19 голосов
/ 01 апреля 2011

Я пытался прочитать двоичный файл побайтно, используя ifstream.Я использовал методы istream, такие как get (), чтобы без проблем прочитать целые куски двоичного файла одновременно.Но моя текущая задача состоит в том, чтобы идти побайтово и полагаться на буферизацию в io-системе, чтобы сделать ее эффективной.Проблема в том, что я, кажется, достиг конца файла на несколько байтов раньше, чем должен был.Поэтому я написал следующую тестовую программу:

#include <iostream>
#include <fstream>

int main() {
    typedef unsigned char uint8;
    std::ifstream source("test.dat", std::ios_base::binary);
    while (source) {
        std::ios::pos_type before = source.tellg();
        uint8 x;
        source >> x;
        std::ios::pos_type after = source.tellg();
        std::cout << before << ' ' << static_cast<int>(x) << ' '
                  << after << std::endl;
    }
    return 0;
}

Это выдает содержимое файла test.dat, по одному байту на строку, показывая положение файла до и после.

Конечно, если мойФайл имеет двухбайтовую последовательность 0x0D-0x0A (что соответствует возврату каретки и переводу строки), эти байты пропущены.

  • Я открыл поток в двоичном режиме.Разве это не мешает интерпретировать разделители строк?
  • Всегда ли операторы извлечения используют текстовый режим?
  • Как правильно читать байты из двоичного istream?

MSVC ++ 2008 в Windows.

Ответы [ 5 ]

18 голосов
/ 01 апреля 2011

Экстракторы >> предназначены для форматированного ввода;они пропускают пробелы (по умолчанию).Для неформатированного ввода одного символа вы можете использовать istream::get() (возвращает int, либо EOF, если чтение не удалось, либо значение в диапазоне [0, UCHAR_MAX]) или istream::get(char&) (ставитсимвол, прочитанный в аргументе, возвращает что-то, что преобразуется в bool, true в случае успешного чтения и false в случае неудачи.

5 голосов
/ 01 апреля 2011

есть функция read () , в которой вы можете указать количество байтов.

4 голосов
/ 01 апреля 2011
source.get()

даст вам один байт. Это неформатированная функция ввода. operator >> - это форматированная функция ввода, которая может подразумевать пропуск пробельных символов.

4 голосов
/ 01 апреля 2011

Почему вы используете форматированное извлечение, а не .read()?

2 голосов
/ 01 апреля 2011

Как уже упоминалось, вы должны использовать istream::read().Но, если вам нужно использовать форматированное извлечение, рассмотрите std::noskipws.

...