3

Linux で開発されたファイル リーダーの古いコードを取り、MSVC++7.1 でコンパイルされた Windows プロジェクトでまったく同じコードを使用しようとしました。コードは問題なくコンパイルされましたが、Windows のファイル リーダーによると、ファイルは空のようでした。

ストリームにエラーフラグを設定せずに、ファイルから何も読み取らなかった ifstream.readsome() まで問題を追跡しました。以下に示すコードは、Linux と Windows のどちらでもコンパイルできますが、Linux では期待どおりに動作します。

このコードはファイルを開き、ファイルの最初の 512 バイトを で 1 回、read()で 1 回読み取りますreadsome()。両方の結果は、プログラムの最後に比較される 2 つのベクトルに格納されます。期待される結果は、2 つのベクトルが等しいことです。

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
4

2 に答える 2

3

readsome()非ブロッキング読み取りを行うためのものです。正確には実装が定義されている(またはカスタム streambuf メンバーによって定義されている)ことを意味するためshowmanyc()、動作は異なる場合があります。どちらも私には正しいようです。

于 2009-07-16T12:55:00.760 に答える
0

そしてアサーション「assert(buf1 == buf2);」buf1 と buf2 はメモリを予約するように指示されただけで (つまり、メモリを割り当てるだけで初期化は行われません)、演算子 == は未定義の値を持つ 2 つのバッファを実際に比較するため、デバッグ モードでコンパイルすると失敗します。

"read(...)" と "readsome(...)" については、ほとんどの場合、"read(...)" を使用することをお勧めします。

于 2009-09-21T20:54:33.593 に答える