プログラムを介してダウンロードしたzipファイルを抽出するために、Ionic.Zip(DotNetZip)を使用しようとしています。しかし、抽出プロセスがいつ完了したかを検出しようとすると行き詰まります。ライブラリには ExtractProgress イベントが含まれているため、進行状況バーで検出しようとしましたが、zip 全体ではなく、すべてのエントリに基づいて進行状況バーを更新します。したがって、最初のファイル エントリが解凍されるとすぐに、「完了」と見なされます。DotNetZip で zip 完了全体の抽出を検出する方法を知っている人はいますか?
4 に答える
DotNetZip Codeplexの例をざっとスキャンすると、zip を一度に 1 アイテムずつ展開しているように見えます。進行状況をユーザーに報告するには、BackgroundWorker
like so を使用します。
public void ExtractFile(string zipToUnpack, string unpackDirectory)
{
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.ProgressChanged += (o, e) => { Console.WriteLine("Percent completed:" + e.ProgressPercentage); };
worker.DoWork += (o, e) =>
{
using (ZipFile zip = ZipFile.Read(zipToUnpack))
{
int step = (zip.Count / 100.0);
int percentComplete = 0;
foreach (ZipEntry file in zip)
{
file.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
percentComplete += step;
worker.ReportProgress(percentComplete);
}
}
};
worker.RunWorkerAsync();
}
また、Codeplex のソース コードを見てみると、かなり完成度の高い製品なので、目的を達成する方法はたくさんあるはずです。私があげたのはそのうちの1つだけです。
HTH、
次のようなコードがある場合:
using (var zip = ZipFile.Read("whatever.zip"))
{
zip.ExtractProgress += MyExtractProgress;
numEntries = zip.Entries.Count;
foreach (var e in zip)
{
e.Extract();
}
}
...抽出進行状況イベントを取得します。ExtractProgressEventArgs クラスについては、こちらに記載されています。event args クラスには、受信したイベントを説明する EventType フィールドがあります。これらのタイプについては、こちらで説明しています。
エントリの抽出開始前、抽出完了後(エントリ) のイベント タイプがあります。そのレベルまで追跡したい場合は、解凍されるデータのチャンクごとに発生するイベント タイプもあります。そのため、特定の抽出に対して何千ものイベントを取得できます。エントリの数を追跡すると、予想される「後」イベントの数がわかり、適切な数の後イベントを受け取ったときに抽出が完了したと宣言できます。
上記で示したように、ループ内の各エントリを抽出している場合、ライブラリは「抽出が完了しました」イベントを発行できません。これは、ループを最後まで続行するか、途中で停止するかがわからないためです。それは知ることができません。
zip.ExtractAll() を呼び出すと、次のようになります。
using (var zip = ZipFile.Read("whatever.zip"))
{
zip.ExtractProgress += MyExtractProgress;
zip.ExtractAll(extractDirectory);
}
...その後、DotNetZip は「すべてのエントリが抽出されました」というイベント タイプを発行します。これは、上記で提供したドキュメント リンクにも記載されています。
したがって、いくつかのオプションがあります。
Extracting_AfterExtractAllという EventTypeを使用して、ExtractAll 操作が完了したかどうかを確認できます。
private void UnZipFile(zipFilePath)
{
using (ZipFile zip = new ZipFile(zipFilePath))
{
zip.ExtractProgress += zip_ExtractProgress;
zip.ExtractAll(Path.GetDirectoryName(zipFilePath));
}
}
static void zip_ExtractProgress(object sender, ExtractProgressEventArgs e)
{
if (e.EventType == ZipProgressEventType.Extracting_AfterExtractAll)
zipExtractFinished = true;
}
これには独自のワーカーを使用する代わりに..サブミッターが参照した ExtractProgress イベントもあり、zip 内のアイテム数を照会することもできます。これら 2 つを組み合わせると、進行状況イベントと、アイテムの総数に対して進行状況を追跡する機能が得られます。私の知る限り、抽出の終了を示すイベントはありません。