C ++二进制文件和迭代器:使用ifstreambuf_iterator以1:1离开? [英] C++ binary files and iterators: getting away with a 1:1 using ifstreambuf_iterator?

查看:180
本文介绍了C ++二进制文件和迭代器:使用ifstreambuf_iterator以1:1离开?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This answer points out the fact that C++ is not well suited for the iteration over a binary file, but this is what I need right now, in short I need to operate on files in a "binary" way, yes all files are binary even the .txt ones, but I'm writing something that operates on image files, so I need to read files that are well structured, were the data is arranged in a specific way.

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

I would like to read the entire file in a data structure such as std::vector<T> so I can almost immediately close the file and work with the content in memory without caring about disk I/O anymore.

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

Right now, the best way to perform a complete iteration over a file according to the standard library is something along the lines of

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();

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

or use std::copy, but even with std::copy you are always using istreambuf iterators ( so if I understand the C++ documentation correctly, you are basically reading 1 byte at each call with the previous code ).

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

So the question is: how do I write a custom iterator ? from where I should inherit from ?

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

I assume that this is also important while writing a file to disk, and I assume that I could use the same iterator class for writing, if I'm wrong please feel free to correct me.

推荐答案

可以优化 std: :copy()使用 std :: istreambuf_iterator< char> 但几乎没有任何实现。只是从某些东西派生出来并不会真正发挥作用,因为这不是迭代器的工作方式。

It is possible to optimize std::copy() using std::istreambuf_iterator<char> but hardly any implementation does. Just deriving from something won't really do the trick either because that isn't how iterators work.

最有效的内置方法可能就是简单地转储文件进入 std :: ostringstream 并从那里获得 std :: string

The most effective built-in approach is probably to simply dump the file into an std::ostringstream and the get a std::string from there:

std::ostringstream out;
out << file.rdbuf();
std::string content = out.str();

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

If you want to avoid travelling through a std::string you could write a stream buffer directly dumping the content into a memory area or a std::vector<unsigned char> and also using the output operation above.

std :: istreambuf_iterator< char> s原则上可以为流缓冲区提供后门并按字符顺序旁路操作。没有这个后门,你将无法使用这些迭代器加速任何事情。 可以使用流缓冲区的 sgetn()在流缓冲区之上创建一个迭代器来处理类似的缓冲区。在这种情况下,您几乎需要一个版本的 std :: copy()来有效地处理段(即缓冲区的每个填充)。如果没有,我只是使用流缓冲区将文件读入缓冲区并迭代它。

The std::istreambuf_iterator<char>s could, in principle have a backdoor to the stream buffer's and bypass characterwise operations. Without that backdoor you won't be able to speed up anything using these iterators. You could create an iterator on top of stream buffers using the stream buffer's sgetn() to deal with a similar buffer. In that case you'd pretty much need a version of std::copy() dealing with segments (i.e., each fill of a buffer) efficiently. Short of either I'd just read the file into buffer using a stream buffer and iterate over that.

这篇关于C ++二进制文件和迭代器:使用ifstreambuf_iterator以1:1离开?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆