ifstream.read () против ifstream.readsome () в MSVC ++ 7.1 - PullRequest
3 голосов
/ 16 июля 2009

Я просто взял какой-то старый код для чтения файлов, который был разработан под 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

Ответы [ 2 ]

3 голосов
/ 16 июля 2009

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

0 голосов
/ 22 сентября 2009

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

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

...