【问题标题】:read part of a file with iostreams使用 iostreams 读取文件的一部分
【发布时间】:2012-01-22 20:17:03
【问题描述】:

我可以打开一个ifstream(或以任何方式设置一个现有的)来只读取文件的一部分吗?例如,我想让我的ifstream 从字节 10 到 50 读取文件。寻找位置 0 将是实际位置 10,读取过去的位置 40(实际上是 50)将导致 EOF 等. 这有可能吗?

【问题讨论】:

    标签: c++ iostream


    【解决方案1】:

    这绝对可以通过实现过滤流缓冲区来完成:您将从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_;
    };
    

    您可以使用指向此流缓冲区实例的指针来初始化std::istream。如果这是一个反复出现的需求,您可能希望创建一个派生自 std::istream 的类,以设置流缓冲区。

    【讨论】:

      【解决方案2】:

      您可以将您想要的字节读入字符串或字符数组,然后您可以将该字符串与 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';
      

      如果你需要处理二进制文件,你也可以这样做:

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

      【讨论】:

      • 需要注意的是,这个解决方案只适用于文本文件。
      • @KhaledNassar:它可以很容易地适应二进制文件。完成。
      • 这种方法的一个问题是要读取的范围可能相当大。当然,如果它确实是巨大的,你可能想要单独处理范围。
      【解决方案3】:

      您可能想要实现自己的流阅读器类(如果存在的话,最好通过一些 ifstream 接口)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-17
        • 2012-05-28
        • 1970-01-01
        • 2011-09-19
        • 2019-05-23
        • 2015-07-16
        • 2016-12-02
        相关资源
        最近更新 更多