0

レガシー システムでのファイル読み取りの問題を解決しようとしています。

これは、同じ SP、SDK、および IDE がインストールされている Windows7/SP1/64 ビット システムでのみテストおよび実行される 32 ビット Windows アプリケーションです。IDE は VS2010/SP1 です。

問題のコードは次のとおりです。

#define ANZSEL 20

int ii, bfil, ipos;

if ((bfil = open("Z:\\whatever.bla", O_RDONLY, 0)) == -1)  { goto end; } // please don't complain about this; it's just here because I didn't want to rephrase the if == -1 above and because it's a legacy codebase; i also tried with UNC paths by the way with the same result

   ii = read(bfil, &some_struct_instance, sizeof(some_struct));
   ipos = _lseek(bfil,0,SEEK_CUR); // ipos shows the correct position here, ie. sizeof(some_struct)
   if (ii == sizeof(some_struct))  {

      ii = read(bfil, &another_struct_instance, sizeof(another_struct)*ANZSEL); // ii here sometimes shows 15 instead of sizeof(another_struct)*ANZSEL
      ipos = _lseek(bfil,0,SEEK_CUR); // ipos always shows the correct value of sizeof(some_struct) + sizeof(another_struct)*ANZSEL
      if (ii == sizeof(another_struct)*ANZSEL)  {

         // should always come here as long as the files' long enough

ご覧のとおり、これは単純な古いダイレクト バイナリをいくつかの構造体に読み込む必要があります。私が観察できるのは、ファイルを作成し、最初に memset/Zeromem で構造体をクリアして、すべてのパディングバイトを 0xCC ではなく 0x00 で「初期化」することです (これは、デバッグモードで mem を非初期化としてタグ付けする Microsoft の方法です)。 stack mem) 以前は正しく動作しなかったシステムで問題が解消されます。

どうすれば問題を「適切に」解決できるかは明らかですが、 open() のように O_BINARY を指定します

if ((bfil = open("Z:\\whatever.bla", O_RDONLY|O_BINARY, 0)) == -1)

なぜこれがこんなに違う振る舞いをするのか、私には何の手がかりもありません。両方のシステムで open() と read() のソースを調べてみましたが、問題を再現できる唯一のシステムにアクセスできることはめったにないため、まだ何も見つけることができませんでした。

したがって、私の質問は、誰かがなぜこれが起こるのかを指摘し、いくつかのドキュメントを参照できるかどうかです.

4

1 に答える 1

3

これは通常、ファイルに値0x1a(別名 control-Z) が含まれている場合に発生します。それ以前の MS-DOS のように、Windows は control-Z をテキスト ファイルの終わりの合図として解釈するため、ファイルをテキスト モードで開いて 0x1a に達すると、単に読み取りを停止します。

すでにわかっているように、ファイルをバイナリ モードで開くと問題が修正されます。0x1a は、ファイルの終わりを示すものとして解釈されなくなります。

于 2014-09-12T13:06:48.430 に答える