.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-Zipプログラム(File.7z is not supported archive)を使用してファイルを抽出できませんでした。
  • 7Zip SDK別名LZMA SDK-これを使用する方法を理解するのに十分なほど賢くないと思います(これが私がここに投稿した理由です)...通常の7zipプログラム?
  • 7-ZipアーカイブDLLのCodeProject C#(.NET)インターフェイス-7zipアーカイブからの抽出のみをサポートしています...それらを作成する必要があります!
  • SharpZipLib-彼らのFAQによると、SharpZipLibは7zipをサポートしていません。

32
すべてのリンクが以下の私の投稿からのものである場合は、Googleからのものであると書かないでください。いくつかの解決策を探すのに時間をかけた人々をあまり尊敬していません。
Patrick Desjardins、

3
私はこの投稿が古いことを知っていますが、今日の私の研究では、SevenZipSharpというプロジェクトを見ました。sevenzipsharp.codeplex.com
Timmerz、

12
今後の読者への警告の一言。SevenZipSharpは放棄されたようです。本日現在、最新の安定版リリース(0.64)が2010年8月にリリースされ、いくつかの厄介なマルチスレッド問題(バグレポートによる)がありました。それ以来、ごく少数のソースコードのコミットが投稿されています。
Anttu

回答:


28

7-zipアプリがすべてのターゲットマシンに(およびパスに)インストールされることを保証できる場合は、コマンドラインアプリ7zを呼び出してオフロードできます。最も洗練された解決策ではありませんが、それは最低の仕事です。


7
実際には、7zコマンドラインユーティリティをバイナリと一緒に出荷し、それにシェルを使用しています。私たちにとって本当にうまくいきます。
David Mohundro、2008年

79

EggCafe 7Zip cookieの例これは、7ZipのDLLを使用した例(zip圧縮cookie)です。

CodePlexラッパー これは、7zの圧縮機能をワープするオープンソースプロジェクトです。

7Zip SDK 7zipの公式SDK(C、C ++、C#、Java)<---私の提案

SharpDevelop.netによる.Net zipライブラリ

7zipを使用したCodeProjectの

SharpZipLib多くの圧縮


完了し、私も役立つオープンソースプロジェクトを追加しました。
Patrick Desjardins、

1
笑?文字列でCookieを変更します...ファイルまたは何か...笑?
Patrick Desjardins、

1
いいえ、私は誰かが実用的な例を思いついたかどうかを確認したいだけです...調査をありがとうございます。
セイバー

2
コピーして貼り付けることができるコードがないことに同意する必要があります。SDKはすべての答えを備えたものですが、機能するものを得るには、いくらかの時間と労力が必要です。あなたがそれをしたくないと理解できます。ごきげんよう。
Patrick Desjardins

3
とにかく、私はSharpDevelop / SharpZipLibの参照を削除することをお勧めします。どちらも同じ参照であり、7-Zipをサポートしていないためです。セイバーは7zを明示的に求めました。ShaprZipLibがアーカイブで機能せず、このスレッドを見つけたため、7zソリューションも探しています。ShaprZipLibは誤解を招くヒントです!
恩賜丸

25

SevenZipSharpは別のソリューションです。7-zipアーカイブを作成...


7
markhorによるこの投稿は、実際にはSevenZipSharpプロジェクトの作成者からのものです。SevenZipSharpは、7Zip dllへのプログラムによるアクセスを可能にし、非常にフル機能を備えています。LZMA SDKは低レベルであり、理解するのが難しいことがわかりました。対照的に、SevenZipSharpは十分に文書化されており、使いやすく、そのテストプロジェクトでは多くのサンプルが使用されています。例を使用すると、ファイルまたはメモリを使用してすばやく圧縮および解凍できます。
John Wigger、

4
SevenZipSharpは放棄されたようです。質問の私の以前のコメントを参照してください。
Anttu 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

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アーカイブにファイルを追加しようとしたところ、アーカイブが破損しました。
Geograph

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(上記のproperty-settingで @Orwellophile ):12 : 26分 :-(
ほぼ同じサイズの出力ファイル。

私自身はc / c ++エンジンに基づくソリューションを使用すると思います。つまり、c#から7zip実行可能ファイルを呼び出すか、7zip c / c ++ dllファイルのラッパーであるsquid-box / SevenZipSharpを使用します。 SevenZipSharpの最新のフォークになる。ラッパーをテストしていませんが、ネイティブ7zipと同じように実行できることを願っています。しかし、うまくいけば、exeを直接呼び出しても明らかにできないストリームを圧縮する可能性が与えられます。それ以外の場合は、exeを呼び出すことよりも利点はあまりないと思います。ラッパーにはいくつかの追加の依存関係があるため、公開されたプロジェクトが「よりクリーン」になりません。

ちなみに、.Net Coreチームは、.Core ver。のsystem.ioクラスにLZMAを実装することを検討しているようです。5、それは素晴らしいでしょう!

(私はこれがコメントではなく回答であることを知っていますが、コードスニペットを提供できるようにするために、コメントにすることはできませんでした)


0

これらの最も簡単な方法は、.7zの代わりに.zipファイルを操作し、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

0

SharpCompressは、私の意見では、最も賢い圧縮ライブラリの1つです。LZMA(7-zip)をサポートし、使いやすく、活発に開発されています。

すでにLZMAストリーミングをサポートしているため、執筆時点では残念ながら7-zipアーカイブの読み取りしかサポートしていません。しかし、アーカイブの書き込みは彼らのtodoリストにあります(readmeを参照)。今後の読者のために:https : //github.com/adamhathcock/sharpcompress/blob/master/FORMATS.mdで現在のステータスを確認してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.