C#
7zip
SevenZipSharp

C#で7zipの圧縮・解凍をする(SevenZipSharp)

C#で7zipの圧縮・解凍をする方法が探しても出てこなかったので書きました。

8年前から更新されていませんが、SevenZipSharpというラッパーライブラリがあります。これを使うのがわかりやすいです。なおこのライブラリ、ドキュメントがほぼ皆無なのでオブジェクトブラウザを見ながら解読しました。

SevenZipSharp
http://sevenzipsharp.codeplex.com/
「SevenZipSharp.dll」をダウンロードします

この他に、7z.dllが必要です。7zipの公式ページからダウンロードしておきます。
7zip Download
http://www.7-zip.org/download.html
x86とx64のうち必要なほうをダウンロードします(以下、x86の場合で書きます)。デフォルトではC:\Program Files(x86)\7-Zipにインストールされる、「7z.dll」を使います。

SevenZipSharp.dllと7z.dllを実行ディレクトリにコピーしておきます。

プロジェクトの参照→参照の追加→参照(B)から、「SevenZipSharp.dll」をプロジェクトに追加します。

圧縮

実行ディレクトリに「archive」というフォルダがあり、これ以下のファイルをarchive.7zとして保存します。

1.1 ディレクトリを圧縮

//using SevenZip;

SevenZipBase.SetLibraryPath("7z.dll");

var compressor = new SevenZipCompressor();
compressor.CompressDirectory(Environment.CurrentDirectory+"\\archive", "archive.7z");

最初にSevenZipBase.SetLibraryPathで7z.dllのある場所を指定します。app.configからも指定できるそうです。
圧縮するディレクトリの引数は相対パスでやると上層のディレクトリ構造を引き継いで圧縮されてしまったので、絶対パスで指定します(絶対パスで指定すると大丈夫です)。

1.2 ファイルを追加して圧縮

compressor.CompressFiles("archive.7z", Directory.GetFiles(Environment.CurrentDirectory +"\\archive"));

1.3 Streamから圧縮

using (var stwt = new StreamWriter("archive.7z"))
{
    compressor.CompressDirectory(Environment.CurrentDirectory + "\\archive", stwt.BaseStream);
}

解凍

2.1 フォルダに解凍

//using SevenZip;

SevenZipBase.SetLibraryPath("7z.dll");

if (!Directory.Exists("decompress")) Directory.CreateDirectory("decompress");
var extractor = new SevenZipExtractor("archive.7z");
extractor.ExtractArchive("decompress");

この場合は相対パスでも平気でしたが、ダメだったら絶対パスにしてみてください。

2.2 メモリに展開

アーカイブの中身をファイルではなくメモリに展開します。

var extractor = new SevenZipExtractor("archive.7z");
foreach (var finfo in extractor.ArchiveFileData)
{
    if (finfo.IsDirectory) continue;//サブフォルダがある場合
    //Console.WriteLine(finfo.FileName);

    using (var ms = new MemoryStream())
    using (var sr = new StreamReader(ms))
    {
        extractor.ExtractFile(finfo.FileName, ms);
        ms.Position = 0;//Positionが最後に行っているので最初に戻す
        var str = sr.ReadToEnd();
        //Console.WriteLine(str);
    }
}

ArchiveFileDataにはアーカイブ内のサブフォルダのファイルも再帰的に格納されます。

2.3 メモリ内に圧縮して解凍

応用例です。ファイルを作らずにメモリ内で圧縮・解凍をします。

using (var archiveMemoryStream = new MemoryStream())
{
    //メモリに圧縮
    var compressor = new SevenZipCompressor();
    compressor.CompressDirectory(Environment.CurrentDirectory + "\\archive", archiveMemoryStream);

    //メモリに解凍
    var extractor = new SevenZipExtractor(archiveMemoryStream);
    foreach(var finfo in extractor.ArchiveFileData)
    {
        if (finfo.IsDirectory) continue;
        //Console.WriteLine(finfo.FileName);

        using (var ms = new MemoryStream())
        using (var sr = new StreamReader(ms))
        {
            extractor.ExtractFile(finfo.FileName, ms);
            ms.Position = 0;
            var str = sr.ReadToEnd();
            //Console.WriteLine(str);
        }
    }
}

以上です。