Разделить ifstream на n потоков? - PullRequest
2 голосов
/ 07 февраля 2020

У меня проблемы с ifstream. Я хочу разделить ifstream на n частей.

Например, n = 3:

  1. Ifstream содержит первую 1/3 файла.
  2. Ifstream включает в себя второе 1/3 файла.
  3. Ifstream включает третью 1/3 файла.
    std::ifstream in("test.txt");
    std::vector<std::string> v1;
    std::vector<std::string> v2;
    std::vector<std::string> v3;

    //first 1/3 of file
    read(in, v1);
    //second 1/3 of file
    read(in, v2);
    //third 1/3 of file
    read(in, v3);

    read(in, v){

         std::string line {""};
         while(getline(in, line)){
              v.pushback(line);
         }
    }

Ответы [ 2 ]

1 голос
/ 07 февраля 2020

@ Mandy007 показал вам простой способ сделать это, предварительно прочитав все содержимое в память.

"Чистый" способ сделать это - определить класс streambuf, полученный делегирует запросы на чтение к базовому istream, но манипулирует позицией поиска и указанием конца файла, чтобы создать видимость того, что область файла является полным потоком.

Так работает настройка в библиотека iostream ... сами классы потока не являются полиморфными c, все поведение происходит из экземпляра streambuf.

1 голос
/ 07 февраля 2020

Вы можете прочитать и вывести sh все строки в векторе, а затем разделить вектор на 3 части, например:

std::string s;
while(!in.eof() && getline(in, s)) v1.push_back(s);
int size = v1.size(), itv2 = 0, itv3 = 0, chunk = v1.size()/3;
for(unsigned i = size-1; i >= size/3; --i, v1.pop_back()) 
    (i > chunk*2)? v3[chunk-itv3++] = v1[i] : v2[chunk-itv2++] = v1[i]; 

И теперь, если вы хотите сделать это для n разделов, вы можете сделать что-то вроде этого:

//n must be defined before use
std::vector<std::vector<std::string> > vChunks(n+1);
std::vector<std::string> v;
std::string s;
while(!in.eof() && getline(in, s)) v.push_back(s);
int size = v.size(), chunk = v.size()/n, r = v.size()%n;
vChunks[n].resize(r);
for(int i = 0; i < n; i++)
    vChunks[i].resize(chunk);
for(int i = v.size()-1, it =1; it <= r; it++, --i, v.pop_back())
    vChunks[n][r-it] = v[i];
for(int i = v.size()-1; i >= 0; --i, v.pop_back())
    vChunks[(i%chunk == 0)? (i-1)/chunk : i/chunk][i%chunk] = v[i];

Где vChunks первые n разделов имеют количество строк между n измерениями и в n + 1 имеет размерность остальных последних строк, если оно не делится на n общее количество строк

...