tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトル解凍せずにZIPファイルへフォルダを追加する方法
記事No11703
投稿日: 2016/08/06(Sat) 16:31
投稿者Kobaちゃん
都度生成されるフォルダを1本のZIPファイルにまとめるソフトを作成しています。
ZIPファイルを解凍することなく、書庫内にフォルダを追加する手段があれば、ご享受お願いしたい。(そもそも技術的に可能?)

現在、下記手段で作成しています。(追加するフォルダが、)例えば100本ある場合、99回の解凍を行うため、最終のZIPファイルを生成するのに時間がかかっています。

ー結合ZIP作成手順ー
<Aフォルダが生成される>
1.Aフォルダを圧縮し、X.zipを作成。
2.Aフォルダを削除。

<Bフォルダが生成される>
3.X.zipを解凍し、生成したAフォルダにBフォルダを追加し、X.zip更新
4.Bフォルダ削除

<Cフォルダが生成される>
   以降、繰り返し

※フォルダ追加はX.zipを解凍するしかないのであれば、A.zip, B.zip, ・・・と作成されたzipをマージしてX.zipを生成するなど。

使用環境:Win7 VB2008Express
VB歴:10年
※Zipは#ziplib or DotNetZipを使ってみましたが結合する(もしくはマージする)機能はありませんでした。

[ツリー表示へ]
タイトルRe: 解凍せずにZIPファイルへフォルダを追加する方法
記事No11704
投稿日: 2016/08/06(Sat) 16:54
投稿者Hongliang
むしろサポートしていないライブラリの方が少ないのでは…。
例えばDotNetZipであれば、New ZipFile(fileName)で既存のzipファイルを開き、AddFileなどして、Save()すればいいです。

[ツリー表示へ]
タイトルRe^2: 解凍せずにZIPファイルへフォルダを追加する方法
記事No11705
投稿日: 2016/08/06(Sat) 20:21
投稿者Kobaちゃん
> むしろサポートしていないライブラリの方が少ないのでは…。
> 例えばDotNetZipであれば、New ZipFile(fileName)で既存のzipファイルを開き、AddFileなどして、Save()すればいいです。
今は、その手順で結合しています。
Aフォルダを圧縮してX.zipを作成。 次に、Bフォルダが生成されたら、X.zipを解凍して復元したAフォルダのルートに、Bフォルダを作成して、この直下にBフォルダのファイルをAddFileで追加して.... 
ただ、この手順では、フォルダが100本(ファイルは総数は概ね1万本)近くあると、100本目のフォルダを結合して最終のX.zipを完成させるのに時間がかかります。 解凍することなく書庫ファイルにフォルダを追加するか、zipファイル同士をマージさせ、処理時間を短縮したい。

[ツリー表示へ]
タイトルRe^3: 解凍せずにZIPファイルへフォルダを追加する方法
記事No11706
投稿日: 2016/08/07(Sun) 01:16
投稿者Hongliang
> Aフォルダを圧縮してX.zipを作成。 次に、Bフォルダが生成されたら、X.zipを解凍して復元したAフォルダのルートに、Bフォルダを作成して、この直下にBフォルダのファイルをAddFileで追加して.... 
> ただ、この手順では、フォルダが100本(ファイルは総数は概ね1万本)近くあると、100本目のフォルダを結合して最終のX.zipを完成させるのに時間がかかります。 解凍することなく書庫ファイルにフォルダを追加するか、zipファイル同士をマージさせ、処理時間を短縮したい。

「解凍して」というのがよく分かりません。
私が書いた手順には、アーカイブファイル内の各エントリの「解凍」処理は含まれません。
実際、DotNetZipおよび(.NET 4.5以降専用の)System.IO.Compression.ZipArchiveで確認しましたが、1MBのファイル100個を追加する処理において、アーカイブ内にエントリが存在していないケースと10000個程度存在しているケースで最大1.3倍程度の差しか出ませんでした。

[ツリー表示へ]
タイトルRe^4: 解凍せずにZIPファイルへフォルダを追加する方法
記事No11707
投稿日: 2016/08/07(Sun) 10:44
投稿者Kobaちゃん
> > Aフォルダを圧縮してX.zipを作成。 次に、Bフォルダが生成されたら、X.zipを解凍して復元したAフォルダのルートに、Bフォルダを作成して、この直下にBフォルダのファイルをAddFileで追加して.... 
> > ただ、この手順では、フォルダが100本(ファイルは総数は概ね1万本)近くあると、100本目のフォルダを結合して最終のX.zipを完成させるのに時間がかかります。 解凍することなく書庫ファイルにフォルダを追加するか、zipファイル同士をマージさせ、処理時間を短縮したい。
>
> 「解凍して」というのがよく分かりません。
> 私が書いた手順には、アーカイブファイル内の各エントリの「解凍」処理は含まれません。
> 実際、DotNetZipおよび(.NET 4.5以降専用の)System.IO.Compression.ZipArchiveで確認しましたが、1MBのファイル100個を追加する処理において、アーカイブ内にエントリが存在していないケースと10000個程度存在しているケースで最大1.3倍程度の差しか出ませんでした。

時間まで調査して頂きありがとうございました。 例が不正確でした。 依頼元の話では場合に
よっては最終X.zipを解凍するのに約5分かかるようですので、かなりのフォルダ数とファイル数
が書庫には入っていると思います。
依頼元の実態を正確に把握していませんでした m(_ _)m これは別の意味で問題ですが(^_^;)

本題に戻りますが

'ZipFileオブジェクトを使って
Dim zf As New ICSharpCode.SharpZipLib.Zip.ZipFile(f) f:ファイルのフルパス
zf.Add(f,エントリパス名)
第2引数でエントリ名を指定しするとできそうです。現在、試しいるところです。

結果がでましたら、投稿する予定です。

BフォルダにあるファイルはBフォルダ直下でなく、....B\bb\b下にあるためこのフォルダ構造を保って
追加したいためZIPファイルにBフォルダを追加という投稿にしました。解凍後は「B\bb\b\ファイル名」
を期待していました。
単純に第1引数にフォルダ名を入れただけでは、解凍後のフォルダ構造が「....B\bb\b\ファイル名」と
なり期待通りでなかったのですが、addメソッドの第2引数でエントリ名(B\bb\b\ファイル名)を指定
するとうまくいきそうです。

[ツリー表示へ]
タイトルRe^5: 解凍せずにZIPファイルへフォルダを追加する方法(解決)
記事No11708
投稿日: 2016/08/07(Sun) 21:10
投稿者Kobaちゃん
> Dim zf As New ICSharpCode.SharpZipLib.Zip.ZipFile(f) f:ファイルのフルパス
> zf.Add(f,エントリパス名)
> 第2引数でエントリ名を指定しするとできそうです。現在、試しいるところです。
>
> 結果がでましたら、投稿する予定です。

解決しました。

X.zipを解凍すると下記のように期待通りのフォルダ構造で解凍できました。

A\aa\a\ファイル1
A\aa\a\ファイル2
B\bb\b\ファイル1
B\bb\b\ファイル2


下記のような感じで作成しました
fileNamには、"....\B\bb\b\ファイル1"または、"....\B\bb\b\ファイル2"が
入ります。

'ZipFileオブジェクトの作成
Dim zf As New ICSharpCode.SharpZipLib.Zip.ZipFile(zipFileNam)

'ZipFileの更新を開始
zf.BeginUpdate()
zf.Add(fileNam, fileNam.Replace("....\", ""))
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
※"....\"(親パスの先頭)を""に置換してエントリ名を定義

'ZipFileの更新をコミット
zf.CommitUpdate()

'閉じる
zf.Close()

[ツリー表示へ]