|
フォルダをZIPファイル圧縮/解凍するサンプル(VB.NET)

|
<このサンプルの概要>
J#.NET(vjslib.dll)を使用してフォルダをまるごと ZIPファイル圧縮/解凍するサンプルです。フォルダを1つの
ファイルとしてバックアップする時に有効な方法だと思います。色々調べましたがこれが一番良い方法では!??
参照設定にvjslibを追加してお試しください。このサンプルの動作環境として.NET Framework2.0 とJ#.NET2.0 で
動作確認しています。VS.NET2005には.NET Framework2.0とJ#.NET2.0が含まれていますが、.NET Framework2.0 ラ
ンタイムには J#.NET2.0ランタイムが含まれていませんので別途ダウンロードする必要があります。
ちなみに、このサンプルはC#をVB.NETに変換したものなので、その逆も簡単なはずです。。。。。。。。。。。。
このサンプルは空のフォルダもZIPに含めるようにしていますが、Compressed (zipped) Foldersで見るとフォルダ
がファイルのように表示されたりします。しかし、解凍(というか展開)してみると問題なく展開されます。空の
フォルダも作成されます。疑問&調査中!!現在愛用しているフリーの解凍ツールでは何の問題も無いのですが。
<このサンプルの見直しが必要な箇所>
(1)ファイルのクローズ処理はtry catch finallyで確実にクローズしましょう!!
(2)進捗状況が分かるようにした方が良いでしょう!!
★フォルダをZIPファイル圧縮/解凍するクラス(JZip.vb)
''' <summary>
''' ZIP圧縮/解凍クラス
''' </summary>
''' <remarks></remarks>
Public Class JZip
''' <summary>
''' 圧縮
''' </summary>
''' <param name="zipFile">ZIPファイル</param>
''' <param name="srcPath">圧縮するFile/Folder</param>
''' <remarks></remarks>
Public Shared Sub Compress(ByVal zipFile As String, ByVal srcPath As String)
' 圧縮するファイルの一覧作成
Dim isFolder As Boolean = False
Dim filePaths(0) As String
If System.IO.Directory.Exists(srcPath) Then
' フォルダの時
Dim fileLists As String = getFolderFileList(srcPath)
If "".Equals(fileLists) = False Then
filePaths = fileLists.Split(vbLf)
isFolder = True
End If
Else
' ファイルの時
filePaths(0) = srcPath
End If
' ZIPファイルオープン
Dim fos As java.io.FileOutputStream = New java.io.FileOutputStream(zipFile)
Dim zos As java.util.zip.ZipOutputStream = New java.util.zip.ZipOutputStream(fos)
' ZIPにファイルを追加する
For Each fpt As String In filePaths
If "".Equals(fpt) Then Continue For
' ZIPに追加するときのファイル名を決定する
Dim f As String
If isFolder = False Then
' ディレクトリ無
f = System.IO.Path.GetFileName(fpt)
Else
' ディレクトリ有
f = fpt.Remove(0, srcPath.Length)
End If
If "\".Equals(f.Substring(0, 1)) Then f = f.Substring(1)
f = f.Replace("\", "/")
' エントリ作成
Dim ze As java.util.zip.ZipEntry = New java.util.zip.ZipEntry(f)
' 圧縮メソッドを設定
ze.setMethod(java.util.zip.ZipEntry.DEFLATED)
' 更新日時設定
ze.setTime(toEpochTime(System.IO.File.GetLastWriteTime(fpt)))
' エントリ追加
zos.putNextEntry(ze)
' 圧縮データ書込
If "\".Equals(fpt.Substring(fpt.Length - 1)) = False Then
Dim len As Integer
Dim buffer(8192 - 1) As SByte
' ファイルオープン
Dim fis As java.io.FileInputStream = New java.io.FileInputStream(fpt)
' ファイル読込み
Do While True
len = fis.read(buffer, 0, buffer.Length)
If len <= 0 Then
Exit Do
End If
' ファイル書込み
zos.write(buffer, 0, len)
Loop
' 閉じる
fis.close()
End If
' 閉じる
zos.closeEntry()
Application.DoEvents()
Next
' ZIPファイルクローズ
zos.close()
fos.close()
End Sub
''' <summary>
''' 解凍
''' </summary>
''' <param name="zipFile">ZIPファイル</param>
''' <param name="dstPath">解凍するFolder</param>
''' <remarks></remarks>
Public Shared Sub Extract(ByVal zipFile As String, ByVal dstPath As String)
' フォルダ作成
If System.IO.Directory.Exists(dstPath) = False Then
System.IO.Directory.CreateDirectory(dstPath)
End If
' ZIPファイルオープン
Dim fis As java.io.FileInputStream = New java.io.FileInputStream(zipFile)
Dim zis As java.util.zip.ZipInputStream = New java.util.zip.ZipInputStream(fis)
' ZIP内のファイル情報を取得
Do While True
Dim ze As java.util.zip.ZipEntry = zis.getNextEntry()
If ze Is Nothing Then Exit Do
' ファイル名取得
Dim fileName As String = ze.getName()
' 解凍先のパス設定
Dim fullPath As String = System.IO.Path.Combine(dstPath, fileName)
fullPath = fullPath.Replace("/", "\")
If ze.isDirectory() = False Then
Dim len As Integer
Dim buffer(8192 - 1) As SByte
' ファイルオープン
Dim fos As java.io.FileOutputStream = New java.io.FileOutputStream(fullPath)
' ファイル読込み
Do While True
len = zis.read(buffer, 0, buffer.Length)
If len <= 0 Then
Exit Do
End If
fos.write(buffer, 0, len)
Loop
' 閉じる
fos.close()
' ファイルの更新日時設定
System.IO.File.SetLastWriteTime(fullPath, fromEpochTime(ze.getTime()))
Else
' フォルダ作成
System.IO.Directory.CreateDirectory(fullPath)
End If
Application.DoEvents()
Loop
' ZIPファイルクローズ
zis.close()
fis.close()
End Sub
''' <summary>
''' フォルダとファイルの一覧を取得
''' </summary>
''' <param name="srcPath">一覧取得するFolder</param>
''' <returns>フォルダとファイルの一覧(改行区切り)</returns>
''' <remarks></remarks>
Private Shared Function getFolderFileList(ByVal srcPath As String) As String
Dim flist As String = ""
Dim current As System.IO.DirectoryInfo = New System.IO.DirectoryInfo(srcPath)
' ファイルの一覧作成
For Each fpt As System.IO.FileInfo In current.GetFiles
If "".Equals(flist) = False Then flist &= vbLf
flist &= fpt.FullName
Next
' フォルダの一覧作成
For Each dir As System.IO.DirectoryInfo In current.GetDirectories
If "".Equals(flist) = False Then flist &= vbLf
flist += dir.FullName + "\"
Dim str As String = getFolderFileList(dir.FullName)
If "".Equals(str) = False Then
If "".Equals(flist) = False Then flist &= vbLf
flist &= str
End If
Next
Application.DoEvents()
Return flist
End Function
''' <summary>
''' DateTimeをエポック値に変換する
''' </summary>
''' <param name="dt"></param>
''' <returns>DateTime</returns>
''' <remarks>エポック値</remarks>
Private Shared Function toEpochTime(ByVal dt As DateTime) As Long
Dim epo As Long = (dt.ToUniversalTime().Ticks - 621355968000000000) / 10000
Return epo
End Function
''' <summary>
''' エポック値をDateTimeに変換する
''' </summary>
''' <param name="epo"></param>
''' <returns>エポック値</returns>
''' <remarks>DateTime</remarks>
Private Shared Function fromEpochTime(ByVal epo As Long) As DateTime
Dim dt As DateTime = New DateTime(epo * 10000 + 621355968000000000)
Return dt.ToLocalTime()
End Function
End Class
★テスト用フォーム(Form1.vb)
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Button1.Click
' フォルダ圧縮
JZip.Compress("d:\temp\test.zip", "d:\temp\test1")
' 解凍
JZip.Extract("d:\temp\test.zip", "d:\temp\test2")
' ファイル圧縮
JZip.Compress("d:\temp\test.zip", "d:\temp\test3\test3.txt")
' 解凍
JZip.Extract("d:\temp\test.zip", "d:\temp\test4")
End Sub
End Class