read part of a file with iostreams

筅森魡賤 提交于 2019-12-03 13:33:00

It definetly can be done by implementing a filtering stream buffer: you would derive from std::streambuf and take the range you want to expose and the underlying stream buffer (well, a pointer to it) as arguments. Then you would seek to the start location. An overridden underflow() function would read from the underlying stream buffer into its buffer until has consumed as many characters as were desired. Here is a somewhat rough and entirely untested version:

#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_;
};

You can use a pointer to an instance of this stream buffer to initialuze an std::istream. If this a recurring need, you might want to create a class derived from std::istream setting up the stream buffer instead.

You could read the bytes that you want into a string or char array, then you can use that string with a istringstream, and use that instead of your ifstream. Example:

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';

If you need to handle binary files, you can do that too:

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

You might want to implement your own stream reader class (preferably via some ifstream interface if one exists).

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!