Страницы

Поиск по вопросам

понедельник, 24 февраля 2020 г.

Как добавить файл в 7-zip архив с сохранением структуры каталогов?

#c_sharp #7z


Использую SevenZipSharp.

    SevenZipCompressor.SetLibraryPath("7z.dll");
    SevenZipCompressor szc = new SevenZipCompressor();
    szc.DirectoryStructure = true;
    szc.PreserveDirectoryRoot = true;
    szc.ZipEncryptionMethod = ZipEncryptionMethod.Aes256;
    szc.CompressionMode = CompressionMode.Create;


Если добавить несколько файлов сразу, то каталоги создаются нормально

    szc.CompressFilesEncrypted("test.7z", "123", @"C:\Test\Test2\123.txt", @"C:\Test\Test\123.txt",
@"C:\Test\123.txt");


А если добавлять по одному, то все файлы записываются в корень архива.

    szc.CompressFilesEncrypted("test.7z", "123", @"C:\Test\Test2\123.txt");
    szc.CompressionMode = CompressionMode.Append;
    szc.CompressFilesEncrypted("test.7z", "123", @"C:\Test\Test\123.txt");
    szc.CompressFilesEncrypted("test.7z", "123", @"C:\Test\123.txt");


В итоге получается 3 файла 123.txt в корне.

Что я делаю не так? Как добавлять по одному файлу с сохранением полного пути?
    


Ответы

Ответ 1



Нужно передавать длину общего пути для всех файлов: string commonPath = "C:\\Test\\"; int commonPathLength = commonPath.Length; szc.CompressFilesEncrypted("test.7z", commonPathLength, "123", @"C:\Test\Test2\123.txt"); szc.CompressionMode = CompressionMode.Append; szc.CompressFilesEncrypted("test.7z", commonPathLength, "123", @"C:\Test\Test\123.txt"); szc.CompressFilesEncrypted("test.7z", commonPathLength, "123", @"C:\Test\123.txt"); Судя по исходникам (к сожалению, у проекта нету документации), метод CompressFilesEncrypted отличает часть пути, которая принадлежит архиву, от части пути внутри архива, при помощи вычисления общей части пути всех переданных файлов. public void CompressFilesEncrypted( string archiveName, string password, params string[] fileFullNames) { CompressFilesEncrypted(archiveName, CommonRoot(fileFullNames), password, fileFullNames); } То есть, если переданы файлы C:\Test\Test2\123.txt и C:\Test\Test4\123.txt, то общей частью будет C:\Test\. А вот для одного файла общей частью оказывается весь путь. Поэтому и приходится вычислять нужную общую длину вручную, и передавать, используя перезагрузку с длиной.

Ответ 2



Для упаковки нескольких файлов предназначен метод CompressFileDictionary - он позволяет полностью контролировать структуру имен в архиве. На вход ему первым аргументом подается Dictionary, с будущим путем в архиве в качестве ключа и настоящим именем архивируемого файла в качестве значения. Если хотите полные имена - просто добавьте полное имя файла одновременно и в ключ и в значение: var archiveName = "C:\\foo\\bar.7z"; var sevenZip = new SevenZipCompressor(); var files = new Dictionary(); foreach (var fileName in Directory.EnumerateFiles("\\\\some-pc\\SomeFiles\\")) { files.Add(fileName, fileName); } foreach (var fileName in Directory.EnumerateFiles("C:\\Another\\Directory")) { files.Add(fileName, fileName); } var fileName = "D:\\And\\Just\\one.file"; files.Add(fileName, fileName); sevenZip.CompressFileDictionary(files, archiveName, "YourPassword"); Если необходимы полные имена unix-подобном стиле - просто отрезайте корневой элемент пути(букву диска либо косую черту в UNC-путях) из внутриархивного названия файла.

Комментариев нет:

Отправить комментарий