lisz-works

プログラミングと興味を貴方に

C# zip圧縮と特定拡張子だけzipする

【スポンサーリンク】

C#

こんにちわlisです!

C#でzip圧縮をする方法と、その応用で特定の拡張子だけzip圧縮する方法です!

ついでに、「特定拡張子の圧縮→圧縮した元ファイルの削除」まで載せています!

参照の追加

プロジェクトの中にある「参照」を右クリックして、「参照を追加」を押します。

参照を追加

「参照マネージャー」が開くので、検索ボックスに

System.IO.Compression

と入力して、出てくる

  1. System.io.Compression
  2. System.io.Compression.FileSystem

にチェックを入れてOKしましょう。

System.io.Compressionは2つありましたが、バージョンが新しい方にしました。

フォルダまるごとzip圧縮

まず対象のフォルダをまるごと圧縮する方法です。

コピペでいけます。

/// <summary>
/// 対象フォルダをzip圧縮
/// </summary>
/// <param name="targetDir">圧縮するフォルダ</param>
/// <param name="zipPath">zipファイルの出力先</param>
private void Dir2Zip(string targetDir, string zipPath)
{
    ZipFile.CreateFromDirectory(targetDir, zipPath, CompressionLevel.Optimal, false, System.Text.Encoding.GetEncoding("Shift_JIS"));
}

圧縮したいフォルダと、zipファイルの出力先を引数に渡すだけで、zipファイルにしてくれます。

特定の拡張子をzip圧縮

さて拡張子を指定して圧縮です。

具体的にやることの順番は

  1. 対象フォルダの対象ファイル一覧を取得
  2. 対象ファイル一覧をzip圧縮

という工程を行っています。

対象フォルダの対象ファイル一覧を取得

こちらでファイル一覧を取得します。

/// <summary>
/// 対象拡張子ののファイルリスト取得
/// </summary>
/// <param name="targetDir">対象フォルダ</param>
/// <param name="ext">拡張子(ex: "*.txt")</param>
/// <returns>ファイルリスト</returns>
private IEnumerable<string> GetLogs(string targetDir, string ext)
{
    return Directory.EnumerateFiles(targetDir, ext);
}

対象ファイル一覧をzip圧縮

こちらで対象ファイルをzip圧縮します。

/// <summary>
/// logをzipに圧縮
/// 追加参照: System.IO.Compression
/// 参考: https://dobon.net/vb/dotnet/file/zipfile.html
/// </summary>
private void ZipLogs(string _baseDir, IEnumerable<string> logs)
{
    string baseDir = AddDirDelimiter(_baseDir);
    string zipPath = baseDir + Now() +  @".zip";
    // zip書庫を開く
    using (ZipArchive a = ZipFile.Open(zipPath, ZipArchiveMode.Update))
    {
        // ログファイル列挙
        foreach (string file in Directory.EnumerateFiles(baseDir, "*.log"))
        {
            string entryName = file.Substring(baseDir.Length);
            if (!File.Exists(file))
            {
                // ファイルではない
                continue;
            }
            ZipArchiveEntry e = a.CreateEntryFromFile(file, entryName);
        }
    }
}

序盤でコールしているAddDirDelimiter()はこちら。

パスの末尾に「\」が付いていなかったらつける処理です。

/// <summary>
/// フォルダパス末尾に区切り文字(\)追加
/// </summary>
/// <param name="path">対象フォルダパス</param>
/// <returns>結果フォルダパス</returns>
public string AddDirDelimiter(string path)
{
    string filePath = path;
    if (!filePath.EndsWith(@"\"))
    {
        filePath += @"\";
    }
    return filePath;
}

使ってみる

さて、最終的にはこんな感じでコールします。

string dir = @"C:\datas\";
IEnumerable<string> files = GetLogs(dir, "*.csv");
ZipLogs(dir, files);

zip圧縮したファイルを消す

「圧縮したら元のファイルは要らない」

というときは、こちらでファイルを削除しちゃいましょう。

/// <summary>
/// ファイル削除
/// </summary>
/// <param name="paths">削除ファイルリスト</param>
private void DeleteFiles(IEnumerable<string> paths)
{
    foreach (string path in paths)
    {
        if (!File.Exists(path))
        {
            continue;
        }
        File.Delete(path);
    }
}

圧縮~削除までの流れはこんな感じ。

string dir = @"C:\datas\";
IEnumerable<string> files = GetLogs(dir, "*.csv");
ZipLogs(dir, files);
DeleteFiles(files);

zip圧縮時に渡しているfilesをそのまま渡すだけなので簡単です。

参考

コチラを参考にしました。ありがとうございました!

itsakura.com

dobon.net

あとがき

C#でzip圧縮と特定拡張子だけzipするでした!

最近久々にC#を触っていますが、C/C++と比べてやはり楽ですね……

ただVSCodeに慣れすぎて、Visual Studioの操作にめっちゃ戸惑いましたが……(笑)

使い出すとやはり楽ですね!

ファイル圧縮関連の操作をしたいときは、是非参考にしてみてください!