書く理由
- あらゆる段階でアーカイブを妨げることができる独自のカスタムツールがあると便利だからです
- 面白いから
- 多くのアーカイバがapi、payを持っているため、他のアーカイバについては最初の引数を参照してください。
技術とライブラリ
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メソッドを解凍するとき、および解凍するときは逆の順序でハンドラーを使用します。 この構造により、プログラムを任意の数の新しいハンドラで補完することが非常に簡単になります(たとえば、他の暗号化または圧縮方式の実装)。
作業アルゴリズム
- アーカイブタイプの検出(圧縮、暗号化)
- アーカイブオブジェクトのリストの読み取り
- 読み取りリストと除外リストに基づいたアーカイブされたオブジェクトの完全なリストの形成
- アーカイブヘッダーの作成(オブジェクトビュー)
- ヘッダー内のオブジェクトの完全なリストを反復処理する
- オブジェクトを処理し、ヘッダーで処理した後にそのサイズのデータを更新し、処理されたコンテンツの一時ファイルに書き込みます。
- ヘッダーをファイルに保存
- ヘッダー処理(圧縮、暗号化)
- 結果のアーカイブファイルをビルドします
実装
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, __); } }
作業結果の比較
やがて、ほぼ同じ結果が検出されなくなりました。
ソースデータ:
- テキストファイルを含むディレクトリ(1 430 Kb)
- 混合データカタログ(18 893 Kb)
テキスト | 混合データ | |
Winrar | 613 | 8 045 |
郵便番号 | 638 | 8 709 |
これ | 588 | 8 655 |
rarおよびzip形式の場合、通常の圧縮パラメーターが設定され、これもプログラムで使用されます。
現在のアーカイブ形式には、ファイルとディレクトリの絶対パスが格納されています。これらを除外して、圧縮をわずかに改善できます。
改善の可能性
- ファイルに関する情報の保存(作成日/変更日、アクセス権)
- マルチスレッドを追加する(一時ファイルの作成を並列化するだけ)
- アーカイブにコメントを追加します
- ファイルをプログラムに関連付ける