read()返回在某些系统上读取的错误字节数

时间:2014-09-12 12:40:04

标签: c++ windows file-io posix-api

我试图解决遗留系统中的文件读取问题。

这是一款经过测试的32位Windows应用程序,仅在Windows7 / SP1 / 64bit系统上运行,它们都安装了相同的SP,SDK和IDE。 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清除结构时,也可以" init"所有填充字节都带有0x00而不是0xCC(这是微软在调试模式下将mem标记为非初始化堆栈内存的方式)问题在系统之前没有正常运行的情况下消失。

虽然我觉得我能怎样才能正确地"解决问题 - 在open()中指定O_BINARY,如

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

我不知道为什么这种行为会如此不同。 我试图在两个系统上逐步浏览open()和read()的来源,但由于我很少能够访问唯一可以重现问题的系统,所以我还无法找到任何东西。

因此,我的问题是,是否有人可以指出为什么会发生这种情况并引用一些文档。

1 个答案:

答案 0 :(得分:3)

当文件包含值0x1a(又名control-Z)时,通常会发生这种情况。与之前的MS-DOS一样,Windows将control-Z解释为发出文本文件结尾的信号,因此当您以文本模式打开文件并达到0x1a时,它只会停止阅读。

正如您已经发现的那样,以二进制模式打开文件可以解决问题 - 0x1a不再被解释为发出文件结束的信号。