Как создать 7-Zip-архивы с .NET?

Как я могу создать 7-Zip-архивы из моего консольного приложения на С#? Мне нужно иметь возможность извлекать архивы, используя обычную, широко доступную 7-Zip- программу.


Вот мои результаты с примерами, представленными в качестве ответов на этот вопрос

  • "Отламывание" до 7z.exe - это самый простой и эффективный подход, и я могу подтвердить, что он работает хорошо. Как упоминает workmad3, мне просто нужно гарантировать, что 7z.exe установлен на всех целевых машинах, что я могу гарантировать.
  • 7Zip в сжатии памяти - это относится к сжатию файлов cookie "в памяти" перед отправкой клиенту; этот метод кажется несколько перспективным. Методы обертки (обертывание LZMA SDK) возвращают тип byte[]. Когда я пишу массив byte[] в файл, я не могу извлечь его с помощью 7-Zip (File.7z is not supported archive).
  • 7zSharp Wrapper (находится на CodePlex) - это обертывает 7z exe/LZMA SDK. Я ссылался на проект из своего приложения, и он успешно создал некоторые архивные файлы, но мне не удалось извлечь файлы с помощью обычной 7-Zip-программы (File.7z is not supported archive).
  • 7Zip SDK aka LZMA SDK - я думаю, я недостаточно умен, чтобы понять, как это использовать (вот почему я размещал здесь)... Любые примеры рабочего кода, демонстрирующие создание архива 7zip, который может быть извлечен регулярная программа 7zip?
  • Интерфейс CodeProject С# (.NET) для DLL файлов с 7-значным архивом - поддерживает только извлечение из архивов 7zip... Мне нужно их создать!
  • SharpZipLib - в соответствии с их часто задаваемыми вопросами SharpZipLib не поддерживает 7zip.

Ответ 1

Если вы можете гарантировать, что приложение 7-zip будет установлено (и в пути) на всех целевых компьютерах, вы можете отключить его, вызвав приложение 7z командной строки. Не самое изящное решение, но это наименьшая работа.

Ответ 2

Пример файла cookie EggCafe 7Zip Это пример (файл cookie ZIP) с DLL-библиотекой 7Zip.

CodePlex Wrapper Это проект с открытым исходным кодом, который деформирует функцию 7z.

7Zip SDK Официальный SDK для предложения 7zip (C, C++, С#, Java) & lt; ---My

Библиотека ZIP.Net от SharpDevelop.net

CodeProject пример с 7zip

SharpZipLib Много молний

Ответ 3

SevenZipSharp - еще одно решение. Создает 7-zip-архивы...

Ответ 4

Здесь приведен полный рабочий пример с использованием SevenZip SDK в С#.

Он будет писать и читать стандартные файлы 7zip, созданные приложением Windows 7zip.

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SevenZip.Compression.LZMA;
using System.IO;
using SevenZip;

namespace VHD_Director
{
    class My7Zip
    {
        public static void CompressFileLZMA(string inFile, string outFile)
        {
            Int32 dictionary = 1 << 23;
            Int32 posStateBits = 2;
            Int32 litContextBits = 3; // for normal files
            // UInt32 litContextBits = 0; // for 32-bit data
            Int32 litPosBits = 0;
            // UInt32 litPosBits = 2; // for 32-bit data
            Int32 algorithm = 2;
            Int32 numFastBytes = 128;

            string mf = "bt4";
            bool eos = true;
            bool stdInMode = false;


            CoderPropID[] propIDs =  {
                CoderPropID.DictionarySize,
                CoderPropID.PosStateBits,
                CoderPropID.LitContextBits,
                CoderPropID.LitPosBits,
                CoderPropID.Algorithm,
                CoderPropID.NumFastBytes,
                CoderPropID.MatchFinder,
                CoderPropID.EndMarker
            };

            object[] properties = {
                (Int32)(dictionary),
                (Int32)(posStateBits),
                (Int32)(litContextBits),
                (Int32)(litPosBits),
                (Int32)(algorithm),
                (Int32)(numFastBytes),
                mf,
                eos
            };

            using (FileStream inStream = new FileStream(inFile, FileMode.Open))
            {
                using (FileStream outStream = new FileStream(outFile, FileMode.Create))
                {
                    SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
                    encoder.SetCoderProperties(propIDs, properties);
                    encoder.WriteCoderProperties(outStream);
                    Int64 fileSize;
                    if (eos || stdInMode)
                        fileSize = -1;
                    else
                        fileSize = inStream.Length;
                    for (int i = 0; i < 8; i++)
                        outStream.WriteByte((Byte)(fileSize >> (8 * i)));
                    encoder.Code(inStream, outStream, -1, -1, null);
                }
            }

        }

        public static void DecompressFileLZMA(string inFile, string outFile)
        {
            using (FileStream input = new FileStream(inFile, FileMode.Open))
            {
                using (FileStream output = new FileStream(outFile, FileMode.Create))
                {
                    SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();

                    byte[] properties = new byte[5];
                    if (input.Read(properties, 0, 5) != 5)
                        throw (new Exception("input .lzma is too short"));
                    decoder.SetDecoderProperties(properties);

                    long outSize = 0;
                    for (int i = 0; i < 8; i++)
                    {
                        int v = input.ReadByte();
                        if (v < 0)
                            throw (new Exception("Can't Read 1"));
                        outSize |= ((long)(byte)v) << (8 * i);
                    }
                    long compressedSize = input.Length - input.Position;

                    decoder.Code(input, output, compressedSize, outSize, null);
                }
            }
        }

        public static void Test()
        {
            CompressFileLZMA("DiscUtils.pdb", "DiscUtils.pdb.7z");
            DecompressFileLZMA("DiscUtils.pdb.7z", "DiscUtils.pdb2");
        }
    }
}

Ответ 5

Я использовал sdk.

например:

using SevenZip.Compression.LZMA;
private static void CompressFileLZMA(string inFile, string outFile)
{
   SevenZip.Compression.LZMA.Encoder coder = new SevenZip.Compression.LZMA.Encoder();

   using (FileStream input = new FileStream(inFile, FileMode.Open))
   {
      using (FileStream output = new FileStream(outFile, FileMode.Create))
      {
          coder.Code(input, output, -1, -1, null);
          output.Flush();
      }
   }
}

Ответ 6

 string zipfile = @"E:\Folderx\NPPES.zip";
 string folder = @"E:\TargetFolderx";

 ExtractFile(zipfile,folder);
public void ExtractFile(string source, string destination)
        {
            // If the directory doesn't exist, create it.
            if (!Directory.Exists(destination))
                Directory.CreateDirectory(destination);

            //string zPath = ConfigurationManager.AppSettings["FileExtactorEXE"];
          //  string zPath = Properties.Settings.Default.FileExtactorEXE; ;

            string [email protected]"C:\Program Files\7-Zip\7zG.exe";

            try
            {
                ProcessStartInfo pro = new ProcessStartInfo();
                pro.WindowStyle = ProcessWindowStyle.Hidden;
                pro.FileName = zPath;
                pro.Arguments = "x \"" + source + "\" -o" + destination;
                Process x = Process.Start(pro);
                x.WaitForExit();
            }
            catch (System.Exception Ex) { }
        }

Просто установите 7 zip из источника и передайте параметр методу.

Благодарю. Пожалуйста, ответьте.

Ответ 7

Я использую этот код

                string PZipPath = @"C:\Program Files\7-Zip\7z.exe";
                string sourceCompressDir = @"C:\Test";
                string targetCompressName = @"C:\Test\abc.zip";
                string CompressName = targetCompressName.Split('\\').Last();
                string[] fileCompressList = Directory.GetFiles(sourceCompressDir, "*.*");

                    if (fileCompressList.Length == 0)
                    {
                        MessageBox.Show("No file in directory", "Important Message");
                        return;
                    }
                    string filetozip = null;
                    foreach (string filename in fileCompressList)
                    {
                        filetozip = filetozip + "\"" + filename + " ";
                    }

                    ProcessStartInfo pCompress = new ProcessStartInfo();
                    pCompress.FileName = PZipPath;
                    if (chkRequestPWD.Checked == true)
                    {
                        pCompress.Arguments = "a -tzip \"" + targetCompressName + "\" " + filetozip + " -mx=9" + " -p" + tbPassword.Text;
                    }
                    else
                    {
                        pCompress.Arguments = "a -tzip \"" + targetCompressName + "\" \"" + filetozip + "\" -mx=9";
                    }
                    pCompress.WindowStyle = ProcessWindowStyle.Hidden;
                    Process x = Process.Start(pCompress);
                    x.WaitForExit();

Ответ 8

Самый простой способ - работать с .zip файлами вместо .7z и использовать Dot Net Zip

При отмене команд 7zip для оболочки есть другие проблемы, такие как пользовательские привилегии, у меня была проблема с SevenZipSharp.

Private Function CompressFile(filename As String) As Boolean
Using zip As New ZipFile()
    zip.AddFile(filename & ".txt", "")
    zip.Save(filename & ".zip")
End Using

Return File.Exists(filename & ".zip")
End Function

Ответ 9

SharpCompress - это, на мой взгляд, одна из самых умных компрессионных библиотек. Он поддерживает LZMA (7-zip), прост в использовании и активно развивается.

Поскольку у него уже есть поддержка потоковой передачи LZMA, на момент написания он, к сожалению, поддерживает только чтение в формате 7-zip-архивов. НО запись в архиве находится в списке задач (см. Readme). Для будущих читателей: проверьте, чтобы получить текущий статус здесь: https://github.com/adamhathcock/sharpcompress/blob/master/FORMATS.md

Ответ 10

Установите пакет NuGet с именем SevenZipSharp.Interop

Затем:

SevenZipBase.SetLibraryPath(@".\x86\7z.dll");
var compressor = new SevenZip.SevenZipCompressor();
var filesToCompress = Directory.GetFiles(@"D:\data\");
compressor.CompressFiles(@"C:\archive\abc.7z", filesToCompress);

Ответ 11

Некоторая дополнительная информация о тесте для кода @Orwellophile с использованием текстового файла размером 17,9 МБ.
Использование значений свойств в примере кода "как есть" окажет ОГРОМНОЕ негативное влияние на производительность, это займет 14,16 секунд.

Задание свойств следующим образом выполняет ту же работу за 3,91 с (например, в архиве будет та же информация о контейнере: вы можете извлечь и протестировать архив с помощью 7zip, но информации об имени файла нет)

Родной 7zip 2 сек.

CoderPropID[] propIDs =  {
  //CoderPropID.DictionarySize,
  //CoderPropID.PosStateBits,
  //CoderPropID.LitContextBits,
  //CoderPropID.LitPosBits,
  //CoderPropID.Algorithm,
  //CoderPropID.NumFastBytes,
  //CoderPropID.MatchFinder,
  CoderPropID.EndMarker
};
object[] properties = {
  //(Int32)(dictionary),
  //(Int32)(posStateBits),
  //(Int32)(litContextBits),
  //(Int32)(litPosBits),
  //(Int32)(algorithm),
  //(Int32)(numFastBytes),
  //mf,
  eos
};

Я провел еще один тест, используя собственный 7zip и файл резервной копии SQL объемом 1,2 ГБ (.bak)
7zip (максимальное сжатие): 1 минута
LZMA SDK (@Orwellophile с указанными выше настройками свойств): 12:26 мин. :-(
Выходной файл примерно одинакового размера.

Так что, думаю, я сам буду использовать решение, основанное на движке c/c++, т.е. либо вызовите исполняемый файл 7zip из c #, либо используйте squid-box/SevenZipSharp, который является оболочкой для файла 7zip c/c++ dll и, похоже, является новейшим форком SevenZipSharp. Не проверял упаковщик, но я надеюсь, что он работает так же, как родной 7zip. Но, надеюсь, это даст возможность сжимать поток также, что вы, очевидно, не можете, если вы вызываете exe напрямую. В противном случае я думаю, что нет никакого преимущества перед вызовом exe. Оболочка имеет некоторые дополнительные зависимости, поэтому ваш опубликованный проект не станет "чище".

Кстати, кажется, что команда .Net Core рассматривает возможность реализации LZMA в классе system.io в .Core ver. 5, это было бы здорово!

(Я знаю, что это своего рода комментарий, а не ответ, но чтобы предоставить фрагмент кода, он не может быть комментарием)