Разделение ifstream в C ++ - PullRequest
       4

Разделение ifstream в C ++

0 голосов
/ 22 декабря 2011

Я новичок в C ++ и, возможно, у меня глупый вопрос.У меня есть ifstream, который я хотел бы разделить примерно пополам.

Рассматриваемый файл - это отсортированный CSV, и я хочу выполнить поиск по первому значению каждой строки файла.

В конечном итоге файл будет очень большим, поэтому я стараюсь не читать каждую строку файла.

Например,

Если файл содержит 7 строк, я бынравится разделять ifstream, чтобы получить 1 поток, содержащий первые 3 строки, и 1 поток, содержащий последние 4 строки.

Ответы [ 2 ]

1 голос
/ 22 декабря 2011

Сначала используйте ответ на на этот вопрос , чтобы определить размер вашего файла.Затем разделите это число на два.Читайте входные данные построчно и записывайте их в первый выходной поток;проверяйте file.tellg() после каждого звонка.Когда вы пройдете половину пути, переключите вывод на второй файл.

Это не будет равномерно разбивать строки между файлами, но общее количество символовэти строки должны быть достаточно близко, и это не будет разбивать ваш файл на середину строки.

0 голосов
/ 22 декабря 2011

Думайте об этом как о реляционной базе данных с одной огромной таблицей.Чтобы найти определенный фрагмент данных, вы можете выполнить последовательное сканирование всей таблицы или использовать индекс (который должен использоваться для типа запроса, который вы хотите выполнить).

ТипичныйИндекс для текстового файла будет представлять собой список смещений внутри файла, отсортированный по выражению индекса.Если файл csv уже отсортирован по определенному столбцу, то смещения в индексе будут возрастать, что полезно знать при построении индекса.

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

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

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

Поскольку это данные CSV, также применяется особый случай: если единственный индекс, который у вас есть, находится в том же порядке, что и файлсами данные и конец записи можно легко определить (т. е. либо у вас фиксированная длина записи, либо имеется четкий разделитель записей, такой как символ EOL), тогда построение фактического индекса можно опустить и угадать значения(для записей фиксированной длины смещение всегда равно временному смещению длины записи в индексе; для отдельных записей вы можете просто перейти в середину записи и искать следующий терминатор; имейте в виду, что при двоичном поиске существуют неприятные угловые случаиВот).Это, однако, означает, что вы всегда будете читать страницы данных здесь, что менее эффективно, чем просто чтение индекса.

...