如何使用.NET创建7-Zip存档?


101

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


这是我的结果,并提供了示例作为对此问题的解答

  • “掏空”到7z.exe-这是最简单,最有效的方法,我可以确认它的效果很好。正如workmad3所述,我只需要保证在所有目标计算机上都安装了7z.exe,这是我可以保证的。
  • 7压缩内存压缩 -这是指在发送到客户端之前“在内存中”压缩cookie;这种方法似乎有些前途。包装器方法(包装LZMA SDK)返回类型byte[]。将byte[]数组写入文件时,无法使用7-Zip(File.7z is not supported archive)提取数组。
  • 7zSharp包装器(位于CodePlex上)-包装7z exe / LZMA SDK。我从我的应用程序中引用了该项目,该项目成功创建了一些存档文件,但是我无法使用常规的7压缩程序(File.7z is not supported archive)提取文件。
  • 7Zip SDK或LZMA SDK-我想我还不够聪明,无法弄清楚如何使用它(这就是我在此处发布的原因)...演示创建7zip存档的工作代码示例,常规的7zip程序?
  • 用于7-Zip存档DLL的CodeProject C#(.NET)接口 -仅支持从7zip存档中提取...我需要创建它们!
  • SharpZipLib-根据他们的常见问题解答,SharpZipLib不支持7zip。

32
当所有链接都来自我下面的帖子时,请不要写Google的邮件。对于花时间为您寻找一些解决方案的人们不是很尊重。
Patrick Desjardins,

3
我知道这篇文章很旧,但是今天我的研究中确实看到了一个名为SevenZipSharp的项目。sevenzipsharp.codeplex.com
Timmerz'5

12
只是对未来读者的警告。SevenZipSharp似乎已经废弃了。截至今天,最新的稳定版本(0.64)早在2010年8月就已发布,其中存在一些令人讨厌的多线程问题(根据错误报告)。此后,仅发布了一些源代码提交
安图2015年

Answers:


28

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


7
实际上,我们附带了二进制文件的7z命令行实用程序并将其外壳了。对我们来说真的很好。
David Mohundro

79

EggCafe 7Zip cookie示例这是具有7Zip DLL的示例(压缩cookie)。

CodePlex包装器 这是一个翘曲7z压缩功能的开源项目。

7Zip SDK适用于7zip(C,C ++,C#,Java)的官方SDK <---我的建议

SharpDevelop.net的 .Net zip库

带有7zip的CodeProject示例

SharpZipLib许多拉链


完成并添加了一个有用的开源项目。
Patrick Desjardins,

1
大声笑?通过字符串,文件或其他任何方式更改Cookie,哈哈?
Patrick Desjardins,

1
不,我只是想看看是否有人提出了一个可行的示例……感谢您的研究,但是您提供的任何链接都无法使我找到可行的方法。
Seibar

2
我必须同意,没有人可以复制和粘贴代码。SDK可以解决所有问题,但是要花一些时间和精力才能使它起作用。我可以理解您不想这样做。祝你今天愉快。
Patrick Desjardins,

3
无论如何,我建议删除SharpDevelop / SharpZipLib引用,因为这两个引用相同,并且它们不支持7-Zip。Seibar明确要求7z。我也在寻找7z解决方案,因为ShaprZipLib不适用于存档,并找到了该线程。ShaprZipLib是一个误导性提示!
Onsokumaru '18年

25

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


7
markhor的帖子实际上来自SevenZipSharp项目的创建者。SevenZipSharp允许对7Zip dll进行编程访问,使其功能非常强大。我发现LZMA SDK是底层的,很难理解。相比之下,SevenZipSharp具有良好的文档记录,易于使用,并且在其测试项目中具有许多示例用法。使用示例,我可以使用文件或内存快速进行压缩和解压缩。
约翰·威格

4
SevenZipSharp似乎被放弃了。请参阅我先前在问题中的评论。
安图2015年

SevenZipSharp很慢。目前,最推荐的解决方案是使用Process.Start(“ 7z.exe ......)
klm_

24

这是在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");
        }
    }
}

15
请注意,这是纯LZMA压缩/解压缩。7zip文件格式是在此之上的一层,该格式允许打包多个文件以及文件名/路径和其他文件metdata。
redcalx 2015年

1
@redcalx是正确的。有人知道如何处理上层7zip层吗?引用另一个SO帖子将是很棒的:)
Christopher J Smith,

8

我使用了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();
      }
   }
}

7
以及如何解压缩文件?我尝试使用SevenZip.Compression.LZMA.Decoder进行相同的操作,并使用Code(stream1,stream2,-1,-1,null)调用它;这给了框架一个数据异常。
卡斯滕

3
 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,然后将参数传递给方法即可。

谢谢。请喜欢答案。


这在7za.exe的Windows服务中为我工作
Marco Duindam

1

我用这个代码

                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();

1

安装名为的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);

我尝试将文件添加到现有的7z归档中,并损坏了存档。
地理

1

使用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并没有优势。包装器还具有一些其他依赖性,因此它不会使您发布的项目变得“干净”。

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

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


0

这些最简单的方法是使用.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

0

我认为SharpCompress是目前最智能的压缩库之一。它支持LZMA(7-zip),易于使用并且正在积极开发中。

由于它已经具有LZMA流支持,因此在编写本文时,不幸的是它仅支持7-zip存档读取。但是归档文件的编写在他们的待办事项清单上(请参阅自述文件)。对于将来的读者:在此处检查以获取当前状态:https : //github.com/adamhathcock/sharpcompress/blob/master/FORMATS.md

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.