2014-07-07 3 views
0
string lineValue; 
    ifstream myFile("file.txt"); 
    if (myFile.is_open()) { 

     //getline(myFile, lineValue); 
     //cout<<lineValue; 

     while (getline(myFile, lineValue)) { 
      cout << lineValue << '\n'; 
     } 
     myFile.close(); 
    } 
    else cout << "Unable to open file"; 

txt файл формиат как этотЧтение текстового файла в блоках-C++

0 1 
1 2 
2 3 
3 4 
4 5 
5 5 
6 6 
7 7 
8 8 
9 9 

Приведенный выше код читает данные из текстового файла строка за строкой, но размер текстового файла довольно большой (10GB). Итак, как читать данные из файла в кусках/блоках с меньшим количеством операций ввода-вывода и эффективно?

+0

Вам нужно будет просмотреть _все_ данные из файла, прежде чем вы начнете его обрабатывать, или вы можете обрабатывать данные независимо для каждой строки? То, что у вас есть, уже довольно эффективно. (не волнуйтесь или попробуйте оптимизировать базовую буферизацию). –

+0

Посмотрите на istream :: читайте, чтобы читать в кусках или блоках, тогда вам понадобится дополнительная обработка для работы с куском, но вы можете сделать меньше чтений. – diverscuba23

+0

@ πάνταῥεῖ Я хочу читать в кусках не целую строку 'string', потому что файл очень большой – Kamsa

ответ

1

Если вы подумываете о чтении в больших кусках данных, вы будете использовать технику, называемую буферизацией. Однако ifstream уже обеспечивает буферизацию, поэтому мой первый шаг будет состоять в том, чтобы увидеть, можете ли вы получить ifstream, выполняющий эту работу за вас.

Я установил бы гораздо больший буфер, чем значение по умолчанию в вашем потоке. Кое-что как

const int BUFSIZE = 65536; 
std::unique_ptr<char> buffer(new char[BUFSIZE]); 

std::ifstream is; 
is.rdbuf()->pubsetbuf(buffer.get(), BUFSIZE); 
is.open(filename.c_str()); 
const int LINESIZE = 256; 
char line[LINESIZE]; 
if (is) { 
    for (;;) { 
     is.getline(line, LINESIZE); 
     // check for errors and do other work here, (and end loop at some point!) 
    } 
} 
is.close(); 

Убедитесь, что ваш буфер живет так долго, как объект ifstream, который его использует.

Если вы обнаружите, что этого недостаточно, вы можете попробовать прочитать фрагменты данных ifstream :: read. Нет гарантии, что это будет быстрее, вам придется время и сравнить варианты. Вы используете ifstream :: читаете что-то вроде этого.

const int BUFSIZE = 65536; 
std::unique_ptr<char> buffer(new char[BUFSIZE]); 

is.read(buffer.get(), BUFSIZE); 

Вы должны будете заботиться писать код для вызова ifstream.read заботясь, чтобы иметь дело с тем, что «линия» ввода может получить расколоть через последовательные блоки (или даже в более чем двух блоков в зависимости от ваших данных и размера буфера). Вот почему вы хотите изменить буфер буфера в качестве первого варианта.

0

Если и только если текстовые строки имеют одинаковую длину, вы можете просто прочитать файл с помощью std::istream::read();.
Размер блока для чтения будет:

block_size = text_line_length * number_of_text_lines; 

Если вы достаточно смелы, чтобы справиться с более сложности или ваши текстовые строки не одинаковой длины, вы можете прочитать произвольную длину символов в векторе и обрабатывать текст из вектора.

Сложности вступают в игру, когда текстовая строка переполняет блок. Подумайте о том, чтобы обрабатывать случай, когда только часть предложения доступна в конце блока.

+0

, если в конце файла размер указанного фрагмента не точно равен оставшемуся размеру файла, а затем отсутствующему фрагменту. Как это решить? – Kamsa

+0

Подумайте. Рисовать картинки. Я предполагаю, что одним из способов было бы скопировать оставшуюся часть куска в верхнюю часть буфера и начать чтение в месте в конце куска. Другой способ - прочитать один байт за раз до конца строки, а затем начать в начале буфера. –

Смежные вопросы