C: теория о том, как извлекать файлы из архивного файла

В CI создана программа, которая может архивировать несколько файлов в файл архива через командную строку. например

$echo 'file1/2' > file1/2.txt $./archive file1.txt file2.txt arhivedfile $cat archivedfile file1 file2 

Как создать процесс, чтобы в моем архивированном файле у меня:

 header file1 end header file2 end 

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

Я застрял на том, где и как начать.

Пожалуйста, может кто-нибудь помочь мне в некоторой логике относительно того, как подойти к извлечению файлов из архивного файла.

Как уже упоминалось ранее, начните с алгоритма. У вас уже есть большая часть деталей.

Есть несколько подходов, которые вы можете предпринять:

  1. Архив случайного доступа.
  2. Архив последовательного доступа.

Архив случайного доступа

Чтобы это сработало, заголовок должен действовать как индекс (например, индексы карты в библиотеке), указывая; (a) где найти начало каждого файла; и (b) длину каждого файла. Алгоритм записи архивного файла может выглядеть так:

  1. Получить список всех файлов из командной строки.
  2. Создайте структуру для хранения метаданных о каждом файле: имя (255 символов), размер (64-битный int), дату и время и разрешения.
  3. Для каждого файла получите его статистику.
  4. Храните статистику каждого файла в массиве структур.
  5. Откройте архив для записи.
  6. Напишите структуру заголовка.
  7. Для каждого файла добавьте его содержимое в файл архива.
  8. Закройте архивный файл.

(В заголовок также должно быть включено количество файлов).

Далее, алгоритм для извлечения файлов:

  1. Получите файл архива из командной строки.
  2. Получить имя файла для извлечения, также из командной строки.
  3. Создайте память для структуры, чтобы читать метаданные о каждом файле.
  4. Прочтите все метаданные из архивного файла.
  5. Найдите имя файла для извлечения всего списка метаданных.
  6. Вычислите смещение в файл архива для начала имени соответствующего файла.
  7. Ищите смещение.
  8. Прочитайте содержимое файла и запишите его в новый файл.
  9. Закройте новый файл.
  10. Закройте архив.

Последовательный доступ

Это проще. Вы можете сделать это сами: подумайте о шагах.

О программировании

Легко понять, как что-то должно работать. Я предлагаю вам сделать шаг назад – то, что ваш учитель должен обсудить в classе, – и попытаться задуматься над проблемой на уровне выше кодирования, потому что:

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

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

Поделитесь и наслаждайтесь.

Один из подходов – подражать формату ZIP: http://en.wikipedia.org/wiki/ZIP_file_format

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

Альтернативой является формат файла TAR: http://en.wikipedia.org/wiki/Tar_file_format

Это предназначено для streamового мультимедиа («ленточный архив»), поэтому каждая запись содержит свои собственные метаданные. Вам нужно отсканировать весь файл для записи, но обычный вариант использования – упаковать / распаковать целые деревья каталогов, так что это не так уж плохо.

Выполнение этого в streamовом режиме, например, tar, возможно, является самой простой реализацией. Сначала напишите магический номер, чтобы вы могли определить, что это ваш формат архива. Затем я предложил использовать stat (2) (это синтаксис человека для страницы stat man, раздел 2), чтобы получить размер архивируемого файла. Собственно, посмотрите внимательно на поля статистики, доступные вам, может быть какая-то интересная информация, которую вы хотите сохранить.

Выпишите необходимую информацию в методе tag = value, по одной в строке. Например:

 FileName=file1.txt FileSize=10 FileDir=./blah/blah FilePerms=0700 

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

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

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

Надеюсь, это поможет. Удачи.