C: теория о том, как извлечь файлы из архивного файла - PullRequest
4 голосов
/ 22 декабря 2010

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

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

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

header
file1
end
header
file2
end

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

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

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

Ответы [ 4 ]

3 голосов
/ 22 декабря 2010

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

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

  1. Архив с произвольным доступом.
  2. Архив с последовательным доступом.

Архив произвольного доступа

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

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

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

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

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

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

Thisэто легче.Вы можете сделать это самостоятельно: продумайте шаги.

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

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

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

Один из подходов заключается в имитации формата ZIP: http://en.wikipedia.org/wiki/ZIP_file_format

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

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

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

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

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

Запишите необходимую информацию в виде тега = значение, по одному на строку. Например:

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

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

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

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

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

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

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

Делись и наслаждайся.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...