C++二进制文件和迭代器:使用ifstreambuf_iterator以1:1离开?

use*_*710 5 c++ file-io iterator fstream c++11

这个答案指出了C++不适合迭代二进制文件的事实,但这就是我现在所需要的,简而言之我需要以"二进制"方式操作文件,是的,所有文件都是二进制文件.txt,但是我正在写一些对图像文件进行操作的东西,所以我需要读取结构良好的文件,如果数据以特定的方式排列.

我想在数据结构中读取整个文件,std::vector<T>因此我几乎可以立即关闭文件并使用内存中的内容而不再关心磁盘I/O.

现在,根据标准库对文件执行完整迭代的最佳方法就是这样

std::ifstream ifs(filename, std::ios::binary);
  for (std::istreambuf_iterator<char, std::char_traits<char> > it(ifs.rdbuf());
       it != std::istreambuf_iterator<char, std::char_traits<char> >(); it++) {
    // do something with *it;
  }
ifs.close();
Run Code Online (Sandbox Code Playgroud)

或使用std::copy,但即使std::copy你总是使用istreambuf迭代器(所以如果我正确理解C++文档,你基本上在使用前面的代码每次调用时读取1个字节).

所以问题是:我如何编写自定义迭代器?我应该从哪里继承?

我认为这在将文件写入磁盘时也很重要,我假设我可以使用相同的迭代器类进行写入,如果我错了请随时纠正我.

Die*_*ühl 2

可以优化std::copy()使用std::istreambuf_iterator<char>,但几乎没有任何实现可以做到这一点。仅仅从某些东西派生也不会真正起作用,因为这不是迭代器的工作方式。

最有效的内置方法可能是简单地将文件转储到 an 中并从那里std::ostringstream获取 a :std::string

std::ostringstream out;
out << file.rdbuf();
std::string content = out.str();
Run Code Online (Sandbox Code Playgroud)

如果您想避免遍历 a,std::string您可以编写一个流缓冲区,直接将内容转储到内存区域或 a 中std::vector<unsigned char>,并使用上面的输出操作。

原则上, sstd::istreambuf_iterator<char>可以具有流缓冲区的后门并绕过字符操作。如果没有后门,您将无法使用这些迭代器来加速任何事情。您可以使用流缓冲区在流缓冲区之上创建一个迭代器sgetn()来处理类似的缓冲区。在这种情况下,您非常需要一个std::copy()有效处理段(即每次填充缓冲区)的版本。如果没有的话,我只需使用流缓冲区将文件读入缓冲区并对其进行迭代。