TIndexRecord = record
Index: DWord;
Offset: DWord;
Size: DWord;
end;
Файл-хранилище (или файл-архив)
Столкнулся с такой проблемой, а именно - для одной задачи необходимо создать файл-хранилище (или файл-архив, не знаю даже как правильно назвать). В общем это один большой файл, в котором хранится множество других файлов. Поясню вкратце, зачем это нужно. Есть одно промышленное приложение, которое сохраняет определенный интервал времени (15 сек примерно) регистрируемую приборами информацию в течении 24х часов. Сохраняет оно в каталог с датой на момент снятия им этой информации, т.е. типа "21.03.2010" и т.д. Файлы эти примерно по 50-80кб размером, в двоичном формате, имеющие имя типа "15-30-45.dat". Короче, нетрудно представить сколько их в каталоге за 24 часа получается (около 6к). И все бы хорошо, только вот после обработки хранится они должны продолжительное время и, что самое ужасное, их частенько нужно для анализа переносить на другой ПК. Этот процесс занимает трындец сколько времени, хотя бы месячный архив.
Так вот, есть идея посредством плагина (оно поддерживает такую возможность) добавить в это нехорошее приложение возможность сохранения в такой файл-хранилище эти данные. То есть, в начале суток создается файл-хранилище и в него, по мере получения данных, будут дописываться все новые и новые файлы. Нечто напоминающее виртуальную файловую систему. Вопрос в том, как организовать хранение имен файлов и где какой начинается-заканчивается. В итоге за сутки получаем один файл мегабайт примерно на 250, который с легкостью можно хоть куда скопировать.
Подобные методы можно наблюдать в игровых приложения, где все ресурсы игры хранятся в нескольких больших файлах. Есть еще такая штука как tar, вроде для этого предназначен, но походу для частого изменения файла он плохо предназначен.
Может кто из вас, уважаемые, сталкивался с такой задачей? Буду признателен если поделитесь ссылками-материалами-советами как организовать это дело.
Если ваше приложение держит DLL плагина постоянно загруженой в памяти все 24 часа, то хорошо - создаём поток на этот "большой файл" один раз при загрузке плагина и держим до выгрузки; если не умеет - создаём потоки каждый раз при генерации нового файла. В этом случае если есть вероятность записи в этот большой файл одновременно несколькими приложениями, то надо принимать меры по блокировке файла на время записи. Хотя, судя по вашему изложению, такой вероятности нет.
Дальше, когда хост-программа собирается генерировать файл, она вам отправляет его содержимое в плагин (как я понял) - ну, а плагин просто дописывает в открытый поток хранилища это содержимое.
Чтобы потом ориентироваться в этой куче данных, можно ввести простой индекс вида:
Код:
Index и Size необязательны, просто они упрощают чтение и навигацию по файлу. Можно добавить ещё полей, сколько хватит фантазии.
Где хранить иднекс - на ваше усмотрение. Обычно его хранят в том же файле, часто в начале, но не редко и дописывают его в конец. Если хранить отдельно, то нужно не перепутать, к какому хранилищу он относится.
Я думаю, в вашем случае оптимальнее отдельный индекс, поскольку его нужно будет обновлять при каждой записи в хранилище, соответственно, он будет менятся в размере, и вам придётся дополнительно подстраивать размер файла хранилища, дабы оно вместило новый индекс и не перезаписало нужные данные.
Короче, это будет медленнее и больше кода.
Ну, а самостоятельное приложение (в смысле не плагин), которые вы по идее должны тоже написать, будет просто читать этот индекс и по желанию пользователя либо извлекать всё его содержимое, либо какие-то отдельные записи.
Перемещаться по хранилищу можно используя поле Offset.
p.s: TAR больше для хранения файлов предназначен, а для вашего случая хватит по-моему обычного большого файла без полей вроде владелец/права на файл, время его создания, имя и т.д. При желании такие поля можно добавить в индекс. Хотя, конечно, если вы хотите использовать какие-то сторонние просмотрщики архивов вроде WinRAR или 7zip, то TAR вам будет удобнее.
Спасибо, многое стало очевидным, дельные предложения.
Мне кажется, что проще написать простой апплет, архивирующий папки (скажем, скрипт для интерпретатора команд ОС), и запускать его стандартным скхедулером ежесуточно. Можете хоть в рар, хоть в тар, хоть в севензи.
Ну, этот вариант тоже рассматривался, потому как лень было шевелится :) Но ввиду того, что архиватор будет наводить паразитную нагрузку на замеряющий ПК, решили не городить костыли и попробовать такой вариант.
а если сбой во время записи большого файла?
Цитата: craftyfox
а если сбой во время записи большого файла?
Ничто не мешает сначала записывать его во временный файл, а потом копировать на место старого. Дольше, зато надёжнее.