Чтение фрагментов из файла в двоичном режиме в буфер и запись этого буфера в другой файл - PullRequest
5 голосов
/ 25 ноября 2011

Я пытаюсь достичь чего-то подобного:

while (ifstream has not been entirely read)
{
   read a chunk of data into a buffer that has size BUFLEN
   write this buffer to ostream
}

Сначала я пытался добиться этого, используя ifstream.eof() в качестве условия, в то время как я слышал, что это не способидти.Я смотрел на другие функции std :: ios :: ifstream, но не могу понять, что еще использовать.

PS: я использую буфер, потому что передаваемый файл может стать очень большим.

Ответы [ 3 ]

7 голосов
/ 25 ноября 2011

Классы iostream позаботятся обо всей необходимой буферизации, так что вам не нужно.Обычная идиома для копирования всего файла просто:

fout << fin.rdbuf();

iostream позаботится обо всей необходимой буферизации.(Это несколько необычное использование <<, поскольку оно не форматирует. Исторические причины, без сомнения.)

Если вам нужен цикл, возможно, потому что вы хотите сделать некоторые преобразования в данных допереписать его, тогда это будет немного сложнее, так как istream::read «терпит неудачу», если он не читает запрошенное количество символов.Из-за этого вы также должны проверить, сколько символов было прочитано, и обработать их, даже если чтение не удалось:

int readCount;
while ( fin.read( &buf[0], buf.size() )
        || (readCount = fin.gcount()) != 0 ) {
    //  ...
    fout.write( &buf[0], readCount );
}

Это довольно уродливо;лучшее решение может заключаться в том, чтобы обернуть буфер в классе и определить operator<< для этого класса.

6 голосов
/ 25 ноября 2011

Функция istream::read возвращает поток, который можно использовать как логическое выражение, поэтому вы можете сделать что-то вроде:

while (is.read(buffer, BUFLEN))
{
    outputfile.write(buffer, is.gcount());
}

if (is.eof())
{
    if (is.gcount() > 0)
    {
        // Still a few bytes left to write
        outputfile.write(buffer, is.gcount());
    }
}
else if (is.bad())
{
    // Error reading
}

Возможно, вы захотите проверить, что запись внутри цикла тоже не завершается.

0 голосов
/ 25 ноября 2011

Ваша логика просто неверна.

Вам нужно сделать это примерно так:

while (a chunk larger than zero could be read)
{
  write chunk to output
}

Посмотрите, как это еще проще?Нет необходимости явно проверять «конец файла», просто читайте данные, пока не произойдет сбой.Тогда все готово.

...