Часто вы получаете архив ZIP, который содержит внутри себя другие ZIP-архивы, образуя вложенную структуру архивов. В таких случаях вы можете захотеть получить плоскую структуру, извлекая все внутренние ZIP-архивы во внешний архив. Чтобы выполнить эту операцию программно, в этой статье показано, как создать плоский ZIP-архив на C#.

C# .NET API для создания плоских ZIP-архивов

Для создания плоских ZIP-архивов мы будем использовать Aspose.ZIP for .NET. Это API архивации, предназначенный для создания и извлечения архивов популярных форматов, включая ZIP, TAR, GZip и 7z. Вы можете либо установить API из NuGet, либо загрузить его DLL из раздела загрузок.

PM> Install-Package Aspose.Zip

Создайте плоский ZIP-архив на C#

Чтобы понять структуру плоского ZIP-архива, давайте рассмотрим пример. Ниже приведен ZIP-архив, внутри которого находится другой ZIP-архив.

parent.zip
 ├first.txt
 ├inner.zip
 │ ├game.exe
 │ └subitem.bin
 └picture.gif

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

flatten.zip
 ├first.txt
 ├picture.gif
 ├game.exe
 └subitem.bin

Давайте посмотрим, как выполнить это преобразование программно. Ниже приведены шаги для создания плоского ZIP-архива на C#.

  • Сначала загрузите родительский ZIP-архив с помощью класса Архив.
  • Затем создайте списки для хранения внутренних записей ZIP для удаления из родительского ZIP, извлеченных записей и их имен.
  • После этого прокрутите каждый ArchiveEntry в родительском ZIP-архиве, используя коллекцию Archive.Entries.
  • Для каждой записи выполните следующие операции:
    • Проверьте, является ли запись ZIP-архивом, используя метод ArchiveEntry.Name.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)).
    • Затем добавьте запись в список записей, которые нужно удалить.
    • Открыть запись в объект MemoryStream с помощью метода ArchiveEntry.Open().CopyTo(MemoryStream).
    • Перебирайте записи внутреннего ZIP-архива и на каждой итерации выполняйте следующие шаги.
      • Добавьте название записи в список добавляемых записей.
      • Затем загрузите запись в MemoryStream, используя метод ArchiveEntry.Open().CopyTo(MemoryStream).
      • Наконец, добавьте запись в список записей, которые будут добавлены в родительский ZIP.
  • Затем просмотрите список внутренних ZIP-архивов и удалите каждую запись с помощью метода Archive.DeleteEntry(ArchiveEntry).
  • Прокрутите список записей, которые нужно добавить в родительский ZIP-файл, и добавьте каждую запись, используя метод Archive.CreateEntry(String, Stream).
  • Наконец, сохраните родительский ZIP-архив, используя метод Archive.Save(String).

В следующем примере кода показано, как создать плоский ZIP-архив на C#.

// Загрузить ZIP-архив
using (Archive outer = new Archive("Archives/nested-archive.zip"))
{
    // Создайте список для удаления внутренних записей ZIP после извлечения
    List<ArchiveEntry> entriesToDelete = new List<ArchiveEntry>();

    // Создайте список для добавления имен файлов во внутренние ZIP-архивы.
    List<string> namesToInsert = new List<string>();

    // Создайте список для добавления потоковых объектов файлов во внутренние ZIP-архивы.
    List<MemoryStream> contentToInsert = new List<MemoryStream>();

    // Перебрать записи в родительском ZIP-архиве
    foreach (ArchiveEntry entry in outer.Entries)
    {
        // Проверьте, является ли запись ZIP-файлом
        if (entry.Name.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) 
        {
            // Добавить запись в список, чтобы сохранить ссылку, чтобы потом удалить ее из архива
            entriesToDelete.Add(entry); 

            // Создайте объект потока, чтобы открыть ZIP-архив
            MemoryStream innerCompressed = new MemoryStream();
            entry.Open().CopyTo(innerCompressed);

            // Загрузите ZIP-архив из объекта потока 
            using (Archive inner = new Archive(innerCompressed))
            {
                // Цикл по записям архива
                foreach (ArchiveEntry ie in inner.Entries) 
                {
                    // Сохранить название записи в списке
                    namesToInsert.Add(ie.Name); 

                    // Извлечь запись архива в объект потока
                    MemoryStream content = new MemoryStream();
                    ie.Open().CopyTo(content);

                    // Добавить запись в список
                    contentToInsert.Add(content);
                }
            }
        }
    }

    // Удалите внутренние ZIP-архивы
    foreach (ArchiveEntry e in entriesToDelete)
        outer.DeleteEntry(e);

    // Вставьте файлы внутренних ZIP-архивов в родительский ZIP-архив
    for (int i = 0; i < namesToInsert.Count; i++)
        outer.CreateEntry(namesToInsert[i], contentToInsert[i]);

    outer.Save("Archives/flatten.zip");
}

Получите бесплатную лицензию API

Вы можете получить бесплатную временную лицензию для использования Aspose.ZIP для .NET без ограничений на пробную версию.

Вывод

В этой статье вы узнали, как программно создать плоский ZIP-архив на C#. В частности, мы продемонстрировали, как создать плоский ZIP-архив, извлекая внутренние ZIP-архивы в родительский ZIP-файл. Кроме того, вы можете посетить документацию, чтобы узнать больше об Aspose.ZIP для .NET. Кроме того, вы можете поделиться с нами своими вопросами через наш форум.

Смотрите также