【发布时间】:2018-04-24 10:50:03
【问题描述】:
问题是:
我有一个在功能齐全的istream 上运行的代码。它使用如下方法:
istream is;
is.seekg(...) // <--- going backwards at times
is.tellg() // <--- to save the position before looking forward
etc.
这些方法仅适用于来自文件的 istream。但是,如果我以这种方式使用cin,它将不起作用--cin 没有保存位置、向前读取然后返回保存位置的选项。
// So, I can't cat the file into the program
cat file | ./program
// I can only read the file from inside the program
./program -f input.txt
// Which is the problem with a very, very large zipped file
// ... that cannot coexist on the same raid-10 drive system
// ... with the resulting output
zcat really_big_file.zip | ./program //<--- Doesn't work due to cin problem
./program -f really_big_file.zip //<--- not possible without unzipping
我可以将cin 读入deque,并处理deque。 1mb deque 缓冲区绰绰有余。然而,这在三个意义上是有问题的:
- 我必须用
deque重写所有内容才能做到这一点 - 它不会像使用
istream那样防弹,因为它的代码已经被调试过 - 似乎,如果我将它实现为
deque有一些困难,有人会过来说,你为什么不像 ___ 那样做呢
创建可用的istream 对象的正确/最有效方法是什么,因为所有成员都处于活动状态,cin istream?
(记住性能很重要)
【问题讨论】:
-
虽然您无法在
std::cin上进行随机访问,但您始终可以在std::cin上“寻找”前进,只需从中读取(丢弃您阅读的内容)。假设您想向前“寻找” 1000 个字符,然后将 read 1000 个字符放入您不使用的缓冲区中。对于较大的文件,循环读取块。 -
你可以看看 boost.iostream;更具体地说,basic_array device 提供了一种将一些连续的字符数组视为可搜索 iostream 的方法...
-
... 可以与 back_insert_device 结合使用,例如,boost 循环缓冲区
-
嗯,该帖子中提议的 streambuf 子类实现对我来说看起来不完整......但我可能是错的,这就是为什么我会使用现成的解决方案,因为所有 iostream 要求都正确,这很无聊而且因此容易出错/耗时......请注意,boost iostream 的那部分只是标题,所以使用它应该没有问题
-
此外,该帖子中第二个答案的作者建议与 boost.iostream 一起提升进程间流。这些为您的问题 IMO 提供了最佳解决方案,无论是通过缓冲流(安全地映射没有副本的 c 数组)或矢量流(允许交换连续容器,一个非常好的优雅解决方案)。这些看起来也只有标题。