C#と諸々

C#がメインで他もまぁ諸々なブログです
おかしなこと書いてたら指摘してくれると嬉しいです(´・∀・`)
つーかコメント欲しい(´・ω・`)

2007/10/21 18:27

ZipPackage (.net framework 3.0, System.IO.Package) - いろいろ備忘録日記

.NET Framework 3.0 から、新しく ZipPackage クラス (System.IO.Packaging) が追加されたそうです。このクラスを使用することで、Zip アーカイブを生成することができます。
( ただし、このクラスの目的は Open Packaging Conventions (OPC) によるパッケージ化であるため、ZIP アーカイブ内に "[Content_Types].xml" というファイルが必ず含まれてしまうようです。 )

このクラスを使用して、Zip アーカイブを生成する PowerShell 関数を書いてみました。


[ パラメータ ]
sourcePath
対象ファイルまたは対象ディレクトリのパス。


[ 戻り値 ]
Zip アーカイブのバイナリデータを表す byte 配列。


[ Create-ZipArchive 関数 ]
function Create-ZipArchive
{
  param([string]$sourcePath)
 
  [System.Reflection.Assembly]::LoadWithPartialName("WindowsBase") | Out-Null;
 
  $source = Get-Item $sourcePath;
  $sourceFiles =
    &{
      if ($source -is [System.IO.FileInfo])
      {
        return @($source);
      }
      elseif ($source -is [System.IO.DirectoryInfo])
      {
        return $source.GetFiles("*", "AllDirectories");
      }
      else
      {
        throw (New-Object "System.IO.FileNotFoundException" @($sourcePath));
      }
    };
 
  $packageStream = New-Object "System.IO.MemoryStream";
  $package = [System.IO.Packaging.Package]::Open($packageStream, "CreateNew");
 
  $baseUri = New-Object "System.Uri" @($sourcePath);
  foreach ($sourceFile in $sourceFiles)
  {
    $sourceFileUri = New-Object "System.Uri" @($sourceFile.FullName);
    $sourceFileRelativeUri = $baseUri.MakeRelativeUri($sourceFileUri);
    $partUri = [System.IO.Packaging.PackUriHelper]::CreatePartUri($sourceFileRelativeUri);
    $part = $package.CreatePart($partUri, "", "Maximum");
    $sourceFileData = [System.IO.File]::ReadAllBytes($sourceFile.FullName);
    $partStream = $part.GetStream();
    $partStream.Write($sourceFileData, 0, $sourceFileData.Length);
  }
 
  $package.Close();
  $result = $packageStream.ToArray();
  $packageStream.Dispose();
 
  return $result;
 
  trap
  {
    if ($() -ne $package)
    {
      $package.Close();
    }
    if ($() -ne $packageStream)
    {
      $packageStream.Dispose();
    }
  }
}



[ 使用例 ]
$zipData = Create-ZipArchive "C:\Work\Directory1";
[System.IO.File]::WriteAllBytes("C:\Work\Directory1.zip", $zipData);



[ 補足 ]
ZipPackage クラスは、コンストラクタを公開していません。代わりに、Package クラス (System.IO.Packaging)Open メソッド を使用して ZipPackage クラスのインスタンスを取得します。


[ 参考 ]
System.IO.Packaging 名前空間
OPC: データのパッケージ化のための新しい標準 -- MSDN Magazine, August 2007


【 ダウンロード 】
自作の PowerShell 関数は、以下の記事からまとめてダウンロードできます。

YokoKen.PowerShell.Scripts

参考になります。
こんにちは。gsf_zero1です。拙作ブログにコメントありがとうございます。
ZipPackageについての記事は書いていたのですが、なんか難しそうだったので
使い方は全然しらべてませんでした。参考になります。m(_ _)m

現状、J#のzipライブラリ(vjslib.dll)か#ZipLibを利用しているのが多いみたいですね。

2007.10.25 15:25 URL | gsf_zero1 #- [ 編集 ]


gsf_zero1さん、こんにちは^^

> 現状、J#のzipライブラリ(vjslib.dll)か#ZipLibを利用しているのが多いみたいですね。

前に、PowerShell で Zip アーカイブを生成する関数を作ろうと思って、Zip を生成するライブラリを調べたんですが、その時はその2つしか見つけることができませんでした。 ( .NET 3.0 リリース後の話です。 )
.NET Framework の基本クラスライブラリで実現したかったので、結局諦めました^^;

今回、gsf_zero1さんの記事で ZipPackage クラスを知ることができて、とてもありがたく思っています m(_ _)m

2007.10.27 14:29 URL | よこけん #Ay6tTHf6 [ 編集 ]

参考にさせて頂きます
サーバの管理者をやっている者です。

当ソース、Windowsサーバで、ログファイルなどを定期的に送信する際に役立つと感じました。

参考にさせて頂きます。ありがとうございます。

2009.06.28 10:57 URL | あきそら #I0gam1TM [ 編集 ]


あきそらさん、コメントありがとうございます。
"[Content_Types].xml" というファイルが含まれてしまうのが難点ですが、それが特に問題で無いのならば結構使い勝手良いかもです。
この記事があきそらさんのお役に立てれば幸いです。

2009.06.29 20:14 URL | よこけん #Ay6tTHf6 [ 編集 ]












トラックバックURL↓
http://csharper.blog57.fc2.com/tb.php/171-8f9df1e4