SourceChord

C#とXAML好きなプログラマの備忘録。最近はWPF系の話題が中心です。

C#でzip圧縮

タイトルの通りですが、C#でzip圧縮をやってみました。
.net 4.5からZipFile/ZipArchiveなどのクラスが追加され、C#から簡単にzipファイルを作ることができるようになってます。

その他のクラスなどのリファレンスは以下を参照
http://msdn.microsoft.com/ja-jp/library/System.IO.Compression%28v=vs.110%29.aspx
http://msdn.microsoft.com/ja-jp/library/ms404280%28v=vs.110%29.aspx

使い方

System.IO.Compression.FileSystemを参照に追加して、
以下のようにたったこれだけのコードでzipファイルに圧縮してまとめることができます。
これは便利!!

            var srcPath = @"C:\temp\test";
            var dstPath = @"C:\temp\archive.zip";
            ZipFile.CreateFromDirectory(srcPath, dstPath);

Officeのドキュメントファイルから画像を抽出する。

ただzipファイルの圧縮/解凍をするだけでは面白くないので、
pptx/docxなどといった、Officeのドキュメントファイルを展開して中に含まれる画像ファイルを抽出するサンプルを作ってみました。


Office2007以降で使われているpptx/xlsx/docxなどの拡張子のファイルは、OpenXMLというフォーマットで定義されています。このフォーマットの実体は特定のフォルダ構造でXMLやいろんなリソースファイルから構成されたフォルダをzip圧縮したものです。

なので、普通にzipファイルとして解凍すると、ドキュメント中に保存されている画像などを見ることができます。


この手のOpenXML形式のOffice系ファイルをC#から扱うには、本来なら↓のOpenXML SDKとかを使った方がいいとは思いますが、まぁ今回はzip解凍で遊んでみるという目的なので。。。w
http://msdn.microsoft.com/ja-jp/library/office/bb448854%28v=office.15%29.aspx
https://github.com/OfficeDev/Open-XML-SDK

サンプルコード

コマンドライン引数で受けたpptx/docx/xlsxのいずれかの拡張子を受けると、ドキュメントファイル内の画像を抽出します。
抽出したファイルはカレントディレクトリにフォルダを作って保存します。
抽出対象ファイルをコマンドライン引数で受け付けるようにしているので、exeにファイルをドロップしても動作します。

        static void Main(string[] args)
        {
            // 対象とするOfficeドキュメントの拡張子
            var targetDocTypes = new[] { "pptx", "docx", "xlsx" };
            // 抽出対象とする画像の拡張子
            var extractExts = new[] {"jpg", "jpeg", "png", "gif", "bmp", "tif", "tiff"};

            // コマンドライン引数が空の時は何もしない
            if (args.Count() == 0)
            {
                Console.WriteLine("コマンドライン引数で対象ファイルを指定してください。");
                return;
            }

            var srcPath = args[0];
            Console.WriteLine(srcPath);

            // 対象ファイルの拡張子をチェック
            var isValidExt = targetDocTypes.Any(o => srcPath.EndsWith(o, StringComparison.OrdinalIgnoreCase));
            if (!isValidExt)
            {
                Console.WriteLine("無効な拡張子のファイルです。");
                return;
            }

            // 出力フォルダ作成
            var dirName = DateTime.Now.ToString("yyyyMMddHHmmss");
            Console.WriteLine(dirName);
            Directory.CreateDirectory(dirName);

            // 対象のドキュメントファイル内を探索
            using (ZipArchive archive = ZipFile.OpenRead(srcPath))
            {
                foreach (ZipArchiveEntry entry in archive.Entries)
                {
                    var isExtractExt = extractExts.Any(o => entry.Name.EndsWith(o, StringComparison.OrdinalIgnoreCase));
                    if (isExtractExt)
                    {
                        // 画像ファイルを見つけたら、出力フォルダに展開する。
                        Console.WriteLine(entry.FullName);
                        entry.ExtractToFile(Path.Combine(dirName, entry.Name));
                    }
                }
            }
        }