【问题标题】:Reading an entire file in binary mode using C++使用 C++ 以二进制模式读取整个文件
【发布时间】:2012-02-09 17:48:48
【问题描述】:

我正在尝试使用 Visual C++ 以二进制模式读取整个 jpg 文件。代码如下:

FILE *fd = fopen("c:\\Temp\\img.jpg", "rb");
if(fd == NULL) {
    cerr << "Error opening file\n";
    return;
}

fseek(fd, 0, SEEK_END);
long fileSize = ftell(fd);
int *stream = (int *)malloc(fileSize);
cout << fileSize << '\n';
fseek(fd, 0, SEEK_SET);
int bytes_read = fread(stream, fileSize, 1, fd);
printf("%i\n", bytes_read);
fclose(fd);

问题在于bytes_read 始终为1。fileSize 变量包含正确的文件大小。所以我不确定为什么 bytes_read 总是 1 并且不等于 fileSize..?

【问题讨论】:

标签: c++ visual-c++


【解决方案1】:
int n_read = fread(stream, fileSize, 1, fd);

返回你得到的大小为 fileSize 的块的数量。在这种情况下 1.

查看 C 标准的第 7.21.8.1 节: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf(第 334 页)

所以你需要将n_readfileSize 相乘才能得到读取的字节数。

【讨论】:

  • 反之,fread(stream, 1, fileSize, fd) 返回读取的字节数。
  • 是的。我认为这个答案 + 你的评论对于 pokiman 来说应该足够了。
【解决方案2】:

如果你想要读取的字节数,你需要像这样切换参数:

int bytes_read = fread(stream, 1, fileSize, fd);

【讨论】:

    【解决方案3】:
    RETURN VALUE
           fread() and fwrite() return the number of items  successfully  read  or
           written  (i.e.,  not the number of characters).  If an error occurs, or
           the end-of-file is reached, the return value is a short item count  (or
           zero).
    

    您告诉它读取 1 个大小为 fileSize 的项目,它确实做到了。

    【讨论】:

      【解决方案4】:

      来自man 3p fread

      fread() 和 fwrite() 返回成功读取或写入的项目数(即,不是字符数)。如果发生错误,或者到达文件结尾,则返回值是一个短项 计数(或零)。

      您告诉它读取 1 个文件长度,这就是它读取的内容。

      【讨论】:

        【解决方案5】:

        在您调用 fread 时,您告诉它读取 1 个字节...

        应该是:fread(stream, 1, filesize, fd);

        【讨论】:

          【解决方案6】:

          在 C++ 中,您可以使用 std::ifstream,它带有惯用的阅读风格:

          std::ifstream file("file.bin", std::ifstream::binary); //binary mode!
          std::istream_iterator<char> begin(file), end);  //setup iterators!
          std::vector<char> v(begin,end);  //read all data into a vector!
          //v contains the binary data, which you can use from now on
          
          //you can get the pointer to the data as
          char *buffer = &v[0];
          size_t sizeOfBuffer = v.size();
          //you can use buffer and sizeOfBuffer instead of v.
          
          //just remember that the lifetime of buffer is tied with the lifetime of v
          //which means, if v goes out scope, the pointer `buffer` will become invalid
          

          希望你阅读上面sn-p中的cmets。 :-)

          【讨论】:

          • 除了istream_iterator 读取格式化输入,跳过空格。 istreambuf_iterator,也许?
          • @Rob:我想,不。 istream_iterator读取数据;它只是迭代流对象本身读取的数据,在这种情况下,它也将读取空白,因为它以std::ifstream::binary 模式打开。
          猜你喜欢
          • 2016-09-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-03
          • 2010-12-05
          • 1970-01-01
          • 2017-10-01
          相关资源
          最近更新 更多