在 C++ 中连续流式传输多个文件

xiv*_*axy 5 c++ c++11

我的问题与此类似,但我没有找到任何有关此问题的 C++ 参考资料。

有一个要读取和处理的大文件列表。创建一个输入流的最佳方法是什么,该输入流可以逐个从文件中获取数据,并在上一个文件结束时自动打开下一个文件?该流将被提供给处理函数,该处理函数跨文件边界顺序读取可变大小的块。

Bar*_*rry 5

您需要做的是提供一个继承自 的类型std::basic_streambuf。有许多神秘的virtual成员函数,与您相关的函数是showmanyc()underflow()uflow()xsgetn()。您需要重载它们,以便在溢出时自动打开列表中的下一个文件(如果有)。

这是一个示例实现。我们充当std::filebuf并只保留deque<string>我们需要读取的下一个文件:

class multifilebuf : public std::filebuf
{
public:
    multifilebuf(std::initializer_list<std::string> filenames)
    : next_filenames(filenames.begin() + 1, filenames.end())
    {   
        open(*filenames.begin(), std::ios::in);
    }   

protected:
    std::streambuf::int_type underflow() override
    {   
        for (;;) {
            auto res = std::filebuf::underflow();
            if (res == traits_type::eof()) {
                // done with this file, move onto the next one
                if (next_filenames.empty()) {
                    // super done
                    return res;
                }
                else {
                    // onto the next file
                    close();
                    open(next_filenames.front(), std::ios::in);

                    next_filenames.pop_front();
                    continue;
                }
            }
            else {
                return res;
            }
        }
    }   

private:
    std::deque<std::string> next_filenames;
};
Run Code Online (Sandbox Code Playgroud)

这样,您就可以使一切对最终用户透明:

multifilebuf mfb{"file1", "file2", "file3"};

std::istream is(&mfb);
std::string word;
while (is >> word) {
    // transaparently read words from all the files
}
Run Code Online (Sandbox Code Playgroud)