ifstream.read() против ifstream.readsome() в MSVC++7.1

Я просто взял старый код программы для чтения файлов, который был разработан под Linux, и попытался использовать тот же самый код в моем проекте Windows, скомпилированном с помощью MSVC++7.1. Код скомпилировался без проблем, но судя по файловому ридеру в Windows файл оказался пустым.

Я отследил проблему до ifstream.readsome(), который ничего не читал из файла, не устанавливая никаких флагов ошибок в потоке. Приведенный ниже код компилируется как в Linux, так и в Windows, но в Linux он работает так, как ожидалось.

Код открывает файл и читает первые 512 байт файла один раз с помощью read() и один раз с readsome(). Оба результата сохраняются в двух векторах, которые сравниваются в конце программы. Ожидаемый результат будет состоять в том, что два вектора равны.

Результат работы программы на Windows XP размещен под исходным кодом.

Если у кого-то есть идеи или предположения, что может пойти не так в этом коде, я бы хотел их услышать.

Полный исходный код демо:

#include <iostream>
#include <fstream>
#include <vector>
#include <cassert>

int main()
{
  const size_t BUFFER_SIZE(512);

  std::ifstream in("some.file", std::ios::in | std::ios::binary);
  if(in.is_open())
  {
    std::vector<char> buf1(BUFFER_SIZE);
    std::vector<char> buf2(BUFFER_SIZE);
    assert(buf1 == buf2);

    if(in.seekg(0, std::ios_base::beg).good())
    {
      //read BUFFER_SIZE bytes from the file using read()
      if(in.read(&buf1[0], buf1.size()).eof())
      {
        std::cerr << "read() only read " << in.gcount() << " bytes." << std::endl;
      }
      else
      {
        std::cout << "read() could read all 512 bytes as expected." << std::endl;
      }
      if(!in.good())
      {
        std::cerr << "read() set an error flag in ifstream." << std::endl;
      }
    }
    else
    {
  std::cerr << "Can not test read()." << std::endl;
    }
    if(in.seekg(0, std::ios_base::beg).good())
{
      //read BUFFER_SIZE bytes from the file using readsome()
      std::streamsize bytesRead = in.readsome(&buf2[0], buf2.size());
      if(bytesRead != BUFFER_SIZE)
      {
        std::cerr << "readsome() only read " << bytesRead << " bytes." << std::endl;
      }
      else
      {
        std::cout << "readsome() could read all 512 bytes as expected." << std::endl;
      }
      if(!in.good())
      {
        std::cerr << "readsome() set an error flag in ifstream." << std::endl;
      }
    }
    else
    {
      std::cerr << "Can not test readsome()." << std::endl;
    }

    //should read from the same file, so expect the same content
    assert(buf1 == buf2);
  }

  return 0;
}

Вывод в Windows XP:

read() could read all 512 bytes as expected.
readsome() only read 0 bytes.
Assertion failed: buf1 == buf2, file [...], line 60

person Community    schedule 16.07.2009    source источник


Ответы (2)


readsome() предназначен для неблокирующего чтения, поскольку именно это означает, что реализация определяется (или определяется вашим пользовательским членом streambuf showmanyc()), поведение может варьироваться. Оба мне кажутся правильными.

person AProgrammer    schedule 16.07.2009

И утверждение "assert(buf1 == buf2);" терпит неудачу при компиляции в режиме отладки, потому что buf1 и buf2 было сказано только зарезервировать память (то есть только выделить память, а не инициализировать ее), а оператор == фактически сравнивает два буфера с неопределенными значениями.

Что касается "read(...)" и "readsome(...)", мой совет - в большинстве случаев придерживаться "read(...)".

person Community    schedule 21.09.2009