Можно ли сделать istream
, который читает несколько файлов?
Да, но вам придется сделать это самостоятельно. Вы можете реализовать свой собственный класс istream
, расширив std::istream
, а затем реализовав методы, которые он определяет:
class custom_istream : public std::istream {
std::ifstream underlying;
//... implement methods
};
Интерфейс std::istream
достаточно гибок, чтобы позволить вам делать то, что вы хотите. Однако , реализация std::istream
потребует много работы, так как вам придется реализовать весь интерфейс.
Есть ли более простое решение?
Если вам нужен только набор функций, предоставляемых std::istream
, вы можете просто написать свой собственный класс.
Например, если вам нужно только прочитать строки из файла, приведенный ниже класс будет отлично работать для нескольких файлов:
class MultiFileReader {
std::ifstream filestream;
std::ios_base::openmode mode;
size_t file_index = 0;
std::vector<std::string> filenames;
void open_next_file() {
file_index++;
filestream = std::ifstream(filenames.at(file_index), mode);
}
public:
MultiFileReader(std::vector<std::string> const& files, std::ios_base::openmode mode)
: filestream(files[0], mode), mode(mode) {}
// Checks if there's no more files to open, and no more to read
// in the current file
bool hasMoreToRead() {
if(file_index == filenames.size()) return false;
if(file_index + 1 == filenames.size())
return not filestream.eof();
return true;
}
std::string read_line() {
if(not hasMoreToRead()) {
throw std::logic_error("No more to read");
}
// If at the end of the file, open the next file
if(filestream.eof()) {
open_next_file();
}
else {
std::string line;
std::getline(filestream, line);
return line;
}
}
};