代码之家  ›  专栏  ›  技术社区  ›  Seibar

如何使用创建7-Zip存档。网?

  •  117
  • Seibar  · 技术社区  · 17 年前

    如何从C#控制台应用程序创建7-Zip存档?我需要能够使用常规的、广泛可用的文件来提取档案 7-Zip 程序。


    以下是我的结果,并提供了一些例子作为这个问题的答案

    • “屏蔽”到7z.exe-这是最简单、最有效的方法,我可以确认 它工作得很好 .As workmad3 mentions ,我只需要保证所有目标机器上都安装了7z.exe,这是我可以保证的。
    • 7Zip in memory compression -这是指在发送到客户端之前,在“内存”中压缩Cookie;这种方法似乎有点前途。包装方法(包装 LZMA SDK )返回类型 byte[] .当我写 byte[] 数组转换为文件,我无法使用7-Zip提取它( File.7z is not supported archive ).
    • 7zSharp 包装器(位于CodePlex上)-包装7z exe/ LZMA SDK 。我从我的应用程序中引用了该项目,它成功创建了一些存档文件,但我无法使用常规的7-Zip程序提取这些文件( File.7z不支持存档 ).
    • 7Zip SDK aka LZMA SDK -我想我还不够聪明,不知道如何使用这个(这就是我在这里发帖的原因)。..是否有任何工作代码示例可以演示如何创建可由常规7zip程序提取的7zip存档?
    • CodeProject C# (.NET) Interface for 7-Zip Archive DLLs -仅支持从7zip存档中提取。我需要创造它们!
    • SharpZipLib -根据他们 FAQ SharpZipLib不支持7zip。
    12 回复  |  直到 9 年前
        1
  •  82
  •   Dylan Patrick Desjardins    7 年前

    EggCafe 7Zip cookie example 这是一个带有7Zip DLL的示例(压缩cookie)。

    CodePlex Wrapper 这是一个开源项目,它扭曲了7z的压缩函数。

    7Zip SDK 7zip官方SDK(C、C++、C#、Java)<---我的建议

    .Net压缩库 SharpDevelop.net

    CodeProject 7zip示例

    SharpZipLib 许多拉链

        2
  •  31
  •   workmad3    17 年前

    如果你能保证7-zip应用程序将安装在所有目标机器上(并在路径中),你可以通过调用命令行应用程序7z来卸载。这不是最优雅的解决方案,但却是最少的工作。

        3
  •  25
  •   markhor    17 年前

    SevenZipSharp 这是另一种解决方案。创建7-zip存档。..

        4
  •  25
  •   Orwellophile    14 年前

    这是一个使用C#中的SevenZip SDK的完整工作示例。

    它将写入和读取由Windows 7zip应用程序创建的标准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
  •  8
  •   WOPR    17 年前

    我用了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
  •  4
  •   EAzevedo Vishal Sen    8 年前
     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 zPath=@"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
  •  2
  •   MrCalvin    6 年前

    我使用这个代码

                    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
  •  1
  •   lifestylebyatom    12 年前

    使用17.9MB文本文件对@Orwellophile代码进行一些额外的测试信息。
    在代码示例中“按原样”使用属性值将对性能产生巨大的负面影响,它需要 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和1.2GB SQL备份文件(.bak)做了另一个测试
    7zip(最大压缩): 1分钟
    LZMA SDK(具有上述属性设置的@Orwellophile): 12:26分钟 :-(
    输出文件大小大致相同。

    所以我想我自己会使用基于c/c++引擎的解决方案,即从c#调用7zip可执行文件或使用 squid-box/SevenZipSharp ,它是一个围绕7zip c/c++dll文件的包装器,似乎是SevenZipSharp的最新分支。 还没有测试包装器,但我希望它能像原生7zip一样运行。但希望它也能提供压缩流的可能性,如果你直接调用exe,显然无法压缩流。否则,我想调用exe并没有什么优势。包装上有一些 additional dependencies 因此,它不会使您发布的项目“更干净”。

    顺便说一句,这似乎是。Net Core团队考虑在中的system.io类中实现LZMA。核心版本5,那太好了!

    (我知道这是一种注释,而不是答案,但为了能够提供代码片段,它不能是注释)

        9
  •  1
  •   Fidel    7 年前

    SharpCompress 在我看来,它是最聪明的压缩库之一。它支持LZMA(7-zip),易于使用,正在积极开发中。

    由于它已经支持LZMA流媒体,在撰写本文时,不幸的是它只支持7-zip存档读取。但归档写作在他们的待办事项列表上(见自述文件)。对于未来的读者:请在此处查看当前状态: https://github.com/adamhathcock/sharpcompress/blob/master/FORMATS.md

        10
  •  0
  •   Brent Hans Olsson    11 年前

    安装名为的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
  •  0
  •   Mario Eis    9 年前

    这些最简单的方法是使用.zip文件而不是.7z,并使用 Dot Net Zip

    在剥离7zip命令到shell时,还有其他问题,比如用户权限,我遇到了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
    
        12
  •  0
  •   Ninad2110    5 年前

    Here 是创建和提取7zip的代码(基于LZMA SDK-C#)

    注意:使用相同代码创建的7z存档可以不存档。由于代码使用LZMA SDK早期版本的托管LZMA

    推荐文章