.NETでZLibベースのアーカイバを作成する



書く理由







技術とライブラリ



zlib.net.dllライブラリ( 公式サイト )が必要になります。

Visual Studio 2010開発環境

C#言語

フレームワーク3.5



参照条件



アーカイバは次のことができるはずです。





設計



アーカイブ形式


最適化により、私は次のオプションに到達しました。

予定
大きさ
アーカイブの種類 1バイト
ヘッダーの長さ(圧縮および暗号化後) 4バイト
タイトル(以下で詳しく検討します) Nバイト
最初のファイルのコンテンツブロック Nバイト
2番目のファイルのコンテンツブロック Nバイト
...... ......
Kthファイルのコンテンツブロック Nバイト


アーカイブヘッダー形式

予定
大きさ
生ヘッダーサイズ 4バイト
ブロック1 Nバイト
ブロック2 Nバイト
...... ......
ブロックK Nバイト


アーカイブヘッダーブロック形式

予定
大きさ
ブロックサイズ 4バイト
絶対パス長 4バイト
絶対パス Nバイト
相対パス長 4バイト
相対パス Nバイト
処理後のオブジェクトサイズ 8バイト




少し説明。 アーカイブファイルの先頭には、アーカイブオブジェクトのすべてのメタデータを収集するヘッダーが保存されます。 ヘッダー自体は、アーカイブファイルと同じ圧縮および暗号化段階を経ます。 ヘッダーが処理後のファイルの内容を格納するブロックになった後、ブロックはマークまで上がります。 ブロック境界の定義は、ブロックのサイズが格納されるヘッダーに続きます。



仕事の一般原則



ユーザーは、必要なファイルハンドラー(アーカイバー、エンコーダー)の接続に基づいて圧縮オプションを設定します。各ハンドラーには、ExecuteとBackExecuteの2つのメソッドが含まれています。 アーカイブするときは、Executeメソッドを呼び出し、BackExecuteメソッドを解凍するとき、および解凍するときは逆の順序でハンドラーを使用します。 この構造により、プログラムを任意の数の新しいハンドラで補完することが非常に簡単になります(たとえば、他の暗号化または圧縮方式の実装)。



作業アルゴリズム



  1. アーカイブタイプの検出(圧縮、暗号化)
  2. アーカイブオブジェクトのリストの読み取り
  3. 読み取りリストと除外リストに基づいたアーカイブされたオブジェクトの完全なリストの形成
  4. アーカイブヘッダーの作成(オブジェクトビュー)
  5. ヘッダー内のオブジェクトの完全なリストを反復処理する
  6. オブジェクトを処理し、ヘッダーで処理した後にそのサイズのデータ​​を更新し、処理されたコンテンツの一時ファイルに書き込みます。
  7. ヘッダーをファイルに保存
  8. ヘッダー処理(圧縮、暗号化)
  9. 結果のアーカイブファイルをビルドします




実装



ZLibは、転送されたデータをバイト配列として圧縮/解凍できます。 実際、これが必要なものすべてであり、使用するものすべてです。 彼はデータを暗号化する方法を知りません。そのため、標準の.NET FrameworkライブラリであるSystem.Security.Cryptographyを使用します。

アーカイブ/解凍のプロセスでは、処理中の現在のオブジェクトに関するデータと、発生したエラーを取得できます。

ファイルの処理中にエラーが発生した場合、ユーザーには4つのアクションの選択肢が提示されます。



ErrorProcessingイベントをコメントアウトするだけで、アクション要求をキャンセルできます。その場合、プログラムは中断されます。

プログラムコードは提供しません。ソースへのリンクを提供します。



直接:

プロジェクト

dll'kiの形で



SVN:

svn://svn.code.sf.net/p/yark/code-0/trunk



プロジェクト:

sourceforge.net/projects/yark



そして使用例:

圧縮


ArchiveProvider compressor = new ArchiveProvider(); using (SaveFileDialog sfd = new SaveFileDialog()) { if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { CompressorOption option = new CompressorOption() { Password = __, WithoutCompress = true___, RemoveSource = true____, Output = sfd.FileName }; //      foreach (string line in lbIncludes.Items) option.IncludePath.Add(line); //      foreach (string line in lbExclude.Items) option.ExcludePath.Add(line); compressor.Compress(option); } }
      
      





解凍


 ArchiveProvider decompressor = new ArchiveProvider(); using (FolderBrowserDialog fbd = new FolderBrowserDialog()) { if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { decompressor.Decompress(__, fbd.SelectedPath, __); } }
      
      







作業結果の比較



やがて、ほぼ同じ結果が検出されなくなりました。

ソースデータ:





テキスト
混合データ
Winrar
613 8 045
郵便番号
638 8 709
これ
588 8 655




rarおよびzip形式の場合、通常の圧縮パラメーターが設定され、これもプログラムで使用されます。

現在のアーカイブ形式には、ファイルとディレクトリの絶対パスが格納されています。これらを除外して、圧縮をわずかに改善できます。



改善の可能性






All Articles