Как избежать фрагментации файлов при записи сотен многомегабайтных файлов?

Мой вопрос похож на Как избежать фрагментации жесткого диска?, но я генерировать несколько сотен файлов в день, размер которых может варьироваться от 2 МБ до 100+ МБ (этот вопрошающий подразумевал, что его файлы были меньше, поскольку он больше беспокоился о загромождении своего диска, моя проблема заключается в производительности при чтении этих файлов). Эти файлы записываются понемногу (данные журнала), что является лучшим способом создания фрагментации. (База данных не вариант.) У меня есть код для дефрагментации после того, как он полностью написан, но производительность страдает из-за того, что файлы считываются обратно в тот же день.

Похоже, способ сделать это предложен How можно ли ограничить фрагментацию файлов при работе с .NET?; хотя у них мало деталей (а я на С++). Я бы использовал SetFilePointerEx() и SetEndOfFile(), чтобы увеличить размер файла до 2 МБ для начала, а затем, когда файл достигнет выделенного размера, я изменю размер на основе наблюдаемых темпов роста. Затем, когда запись будет завершена, измените размер до фактического размера данных.

Я вижу одну ловушку (на самом деле http://www.cplusplus.com/forum/windows/22114/ указал на это) — это то, что происходит, если моё приложение дает сбой или компьютер выключается. Теперь у меня есть неопределенные данные в моем файле, и я не могу обнаружить их через Windows. Это предполагает, что я создаю файл для отслеживания того, сколько данных было записано либо в файл, либо в один файл. Есть ли лучшая стратегия? Возможно, запись достаточного количества нулей после каждой записи, чтобы можно было обнаружить позже (а затем резервное копирование, чтобы быть готовым к следующей записи)?

Вы видите какие-либо другие ошибки, которые я пропустил?


person MrPhilTX    schedule 04.05.2012    source источник


Ответы (1)


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

Если ваши данные текстовые, это может быть немного сложнее, но вы можете просто написать в конце, игнорируя нулевые данные, возможно, перескочив вперед к границе 2 МБ?

person Deanna    schedule 08.05.2012
comment
Это двоичные данные. Это идея - пожертвовать пространством (по крайней мере, в краткосрочной перспективе) для простоты реализации. Используете ли вы API SetEndOfFile()? Почему-то меня это нервирует. - person MrPhilTX; 08.05.2012
comment
Да, вместе с SetFilePointerEx(). - person Deanna; 09.05.2012