2016-01-04 3 views
0

Моя задача - реорганизовать большой (~ 1 ГБ) двоичный файл. Мне нужно получить значения разных типов и записать их обратно в один большой файл, транспонированный. Исходный файл выглядит так (V означает значение)Как эффективно записывать данные в тысячи разных файлов

V1.1, V2.1, V3.1 ... VX.1, V1.2, V2.2, V3.2, ... VX.2 ... ... VX.Y

Выходной файл должен выглядеть следующим образом: V1.1, V1.2 ... V1.Y, V2.1, V2.2 ... VX. Y.

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

Мои ограничения являются:
- Память (то будет самое главное, 0 будет лучше) - Speed ​​(моя задача состоит в том, чтобы сделать это как можно быстрее)

Моя задача сейчас: - При использовании Filestreams или FILE * Я ограничен 2048 файлами за процесс. В этом исходном файле может быть больше 2000 значений. - Использование CreateFile очень, очень медленно.

Как я читал данные: Я знаю, сколько значений в одном блоке (то есть: V1.1 - VX.1 -> X = 1000) Файл ввода является ifstream, где я прочитал данные в вектор байта, , тогда я записываю каждое значение в FILE * через fwrite(). Затем я прочитал следующий блок V1.2 - VX.2 и так далее ...

Мой вопрос теперь:

Есть ли способ, как правильно справиться с такой ситуацией? Я знаю, что у меня будет компромисс. Как я могу ускорить эту вещь, не набрав слишком большого объема памяти?

заранее спасибо, Nicolas

Edit: ОС Windows XP Embedded, .NET 4.0 Edit: Размер исходного файла ~ 1GB

Edit: Мой первый подход заключается в создании файла скелета и заполните его данными , используя fseek, но это было еще медленнее, чем мой текущий подход.

Редактировать: программа будет работать на жестком диске RAID-1.

+3

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

+0

Насколько велик «большой»? – molbdnilo

+0

ОС - это окна, в деталях XP Embedded, .NET 4.0 –

ответ

0

Вы можете использовать external sorting

Эти алгоритмы разработаны специально для этого именно: сорт (a.k.a ваш Перестановка) файл, содержимое которого не умещается в памяти.

Необходимо выполнить поиск библиотеки для реализации такого алгоритма. Рекомендации по программному обеспечению не являются ontopic на этом сайте.

0

Вы можете попробовать модифицировать свой алгоритм, как это:

Вместо того, чтобы один файл на значение, вы можете иметь файл для позволяет говорить 10 значений. Теперь у вас в 10 раз меньше файлов. Теперь остальное - сортировать каждый из этих файлов.В зависимости от их размера вы можете отсортировать их в ОЗУ или создать 10 файлов для каждого значения и объединить их.

1

По современным меркам, 1 ГБ является небольшой. Вы можете легко позволить себе удерживать вывод в основной памяти, так как вы последовательно вводите вход.

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

Скажите, что вы выбираете 64 kB chunksize. Вы знаете, что выход 1 ГБ содержит 16384 таких выходных блоков. Поэтому вы читаете входной файл 16384 раз, на каждом проходе извлекаете соответствующие значения из ввода, предназначенного для этого конкретного выходного блока.

Очевидно, что подход «1 ГБ за один раз» - это всего лишь предельный случай выбора огромного куска, поэтому у вас есть только один проход. Таким образом, самый эффективный подход - захватить самый большой возможный блок памяти. Разделите размер ввода на размер этого блока, чтобы получить количество проходов, и многократно читайте ввод.

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