MSVC++7.1 中的 ifstream.read() 与 ifstream.readsome()

发布于 2024-07-27 14:55:29 字数 2480 浏览 2 评论 0原文

我只是采用了在 Linux 下开发的文件阅读器的一些旧代码,并尝试在使用 MSVC++7.1 编译的 Windows 项目中使用相同的代码。 代码编译没有任何问题,但根据 Windows 上的文件阅读器,该文件似乎是空的。

我跟踪问题到 ifstream.readsome() 没有从文件中读取任何内容,也没有在流上设置任何错误标志。 下面提供的代码可以在 Linux 和 Windows 上编译,但在 Linux 上它可以按预期工作。

该代码打开一个文件,并使用 read() 读取文件的前 512 个字节一次,使用 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

I just took some older code of a file reader that had been developed under Linux and tried to use that very same code in my Windows project compiled with MSVC++7.1. The code compiled without any problems, but the file seemed to be empty according to the file reader on Windows.

I tracked the problem down to ifstream.readsome() that didn't read anything from the file, without setting any error flags on the stream. The code provided below compiles on either Linux and Windows, but Linux it works as expected.

The code opens a file and reads the first 512 bytes of the file one time with read() and one time with readsome(). Both results are stored in two vectors that are compared at the end of the program. The expected result would be that the two vectors are equal.

The result output of the program on Windows XP is posted below the source code.

If anyone has any ideas or guesses what might go wrong in this code, I'd love to hear them.

Full source code of demo:

#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;
}

Output on Windows XP:

read() could read all 512 bytes as expected.
readsome() only read 0 bytes.
Assertion failed: buf1 == buf2, file [...], line 60

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

平安喜乐 2024-08-03 14:55:29

readsome() 用于进行非阻塞读取,因为确切地说,这意味着实现定义(或由您的自定义 Streambuf 成员 showmanyc() 定义),行为可能会有所不同。 两者对我来说似乎都是正确的。

readsome() is there to make non blocking reads, as what precisely that means is implementation defined (or defined by your custom streambuf member showmanyc()), behaviour can vary. Both seem correct to me.

兲鉂ぱ嘚淚 2024-08-03 14:55:29

以及断言“assert(buf1 == buf2);” 在调试模式下编译时失败,因为 buf1 和 buf2 仅被告知保留内存(即仅分配内存,而不是初始化它),并且运算符 == 实际上比较两个具有未定义值的缓冲区。

至于“read(...)”和“readsome(...)”,我的建议是在大多数情况下坚持使用“read(...)”。

And the assertion "assert(buf1 == buf2);" fails when compiling in debug mode because buf1 and buf2 were only told to reserve memory (that is only to allocate memory, not to initialize it), and the operator == actually compares two buffers having undefined values.

As for "read(...)" and "readsome(...)", my advice is to stick with "read(...)" for most cases.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文