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

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

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

这是一个 32 位 Windows 应用程序,仅在安装了相同 SP、SDK 和 IDE 的 Windows7/SP1/64 位系统上测试和运行。 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 清除结构时,还使用 ​​0x00 而不是 0xCC “初始化”所有填充字节(这是微软在 Debug模式下将 mem 标记为未初始化的方式stack mem) 问题在系统上消失了,之前它没有正确运行。

虽然我似乎很清楚如何“正确地”解决问题 - 在 open() 中指定 O_BINARY 之类的

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

我不知道为什么这会表现得如此不同。 我试图在这两个系统上逐步查看 open() 和 read() 的源代码,但是由于我很少访问唯一可以重现问题的系统,所以我还没有找到任何东西。

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

最佳答案

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

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

关于c++ - read() 返回在某些系统上读取的错误字节数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25808545/

相关文章:

windows - 汇编语言 (MASM) 和 Spectre : Variant 2 (CVE-2017-5715) Branch Target Injection

windows - 密码保护 IIS 目录

java - 如何在 Java 中向现有文件追加文本?

c++ - 调用 lambda 而不将其绑定(bind)到标识符

c++ - TCHAR[] 转换为字符串

windows - UNIX 与 Windows 内存释放

java - 为什么 dir.mkdir() 不需要异常处理,而 file.createNewFile() 需要?

java - 如何将数据从文本文件导入到 JTextArea?

c++ - 数组作为C++类成员变量

c++ - 字符串迭代器不可取消引用的 C++ 问题