我可以打开ifstream(或以任何方式设置现有的)只读取文件的一部分吗?例如,我想让我ifstream从第10字节到第50页读取一个文件.寻找位置0实际上是位置10,读取过去位置40(实际上是50)会在a EOF等中重新生成.这是否可能在任何位置办法?
它绝对可以通过实现一个过滤流缓冲区来实现:你可以从std::streambuf你想要公开的范围和基础流缓冲区(以及它的指针)中获取并作为参数.然后你会寻找起始位置.重写的underflow()函数将从底层流缓冲区读取到其缓冲区中,直到消耗了所需数量的字符.这是一个有点粗糙和完全未经测试的版本:
#include <streambuf>
struct rangebuf: std::streambuf {
rangebuf(std::streampos start,
size_t size,
std::streambuf* sbuf):
size_(size), sbuf_(sbuf)
{
sbuf->seekpos(start, std::ios_base::in);
}
int underflow() {
size_t r(this->sbuf_->sgetn(this->buf_,
std::min<size_t>(sizeof(this->buf_), this->size_));
this->size -= r;
this->setg(this->buf_, this->buf_, this->buf_ + r);
return this->gptr() == this->egptr()
? traits_type::eof()
: traits_type::to_int_type(*this->gptr());
}
size_t size_;
std::streambuf* sbuf_;
};
Run Code Online (Sandbox Code Playgroud)
您可以使用指向此流缓冲区实例的指针来初始化std::istream.如果这是一个经常性的需求,您可能希望创建一个派生自std::istream设置流缓冲区的类.
您可以将所需的字节读入字符串或char数组,然后可以将该字符串与istringstream一起使用,并使用它而不是ifstream.例:
std::ifstream fin("foo.txt");
fin.seekg(10);
char buffer[41];
fin.read(buffer, 40);
buffer[40] = 0;
std::istringstream iss(buffer);
for (std::string s; iss >> s; ) std::cout << s << '\n';
Run Code Online (Sandbox Code Playgroud)
如果您需要处理二进制文件,您也可以这样做:
std::ifstream fin("foo.bin", std::ios::binary | std::ios::in);
fin.seekg(10);
char buffer[40];
fin.read(buffer, 40);
std::istringstream(std::string(buffer, buffer+40));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4706 次 |
| 最近记录: |