圧縮ファイルといえば、国内ではLZHの拡張子を持つLHA圧縮ファイルがスタンダードだが、世界的にはZIPファイルが主流である。
ZIPファイルの解凍(展開)や情報取得には、UnZip32.DLLを使う。(最近になって、 7-zip32.DLLが使える ようになりました。)
UnZip32.DLLは、複数の種類のものがあるので注意が必要だ。ひとつはInfo-ZIP製のもの、もうひとつは「
統合アーカイバラブラリー
」でのshoda T.氏が作成したもの。
shoda T.氏が作成したものは、Info-ZIP製のソースを元に、日本語ファイル名などが正しく扱えるように修正し、「
統合アーカイバラブラリー
」のAPIを含んだものなので、上位互換となっている。
よって、こちらを使う。
UnZip32.DLLおよび、使用方法などのドキュメントは、 http://www.csdinc.co.jp/archiver/ で入手することができる。
さて、使用するAPIは、「統合アーカイバライブラリ」で決められているのでUnLHA32.DLLなどとほとんど同じである。
書庫ファイルの情報を取り出すには、
UnZipOpenArchive, UnZipCloseArchive, UnZipFindFirst,
UnZipFindNextを使用する。
古いバージョンのUnZip32.DLLや、Info-ZIP製のUnZip32.DLLには、これらのAPIが実装されてないので注意が必要だ。
Option Explicit Private Const FNAME_MAX32 = 512 Private Const FNAME_MAX32PLUS1 = FNAME_MAX32 + 1 ' INDIVIDUALINFO構造体 Private Type tagINDIVIDUALINFO dwOriginalSize As Long ' /* ファイルのサイズ */ dwCompressedSize As Long ' /* 圧縮後のサイズ */ dwCRC As Long ' /* 格納ファイルのチェックサム */ uFlag As Long ' /* 処理結果 */ uOSType As Long ' /* 書庫作成に使われたOS */ wRatio As Integer ' /* 圧縮率 */ wDate As Integer ' /* 格納ファイルの日付(DOS 形式) */ wTime As Integer ' /* 格納ファイルの時刻(〃) */ szFilename As String * FNAME_MAX32PLUS1 ' /* 書庫名 */ dummy1 As String * 3 szAttribute As String * 8 ' /* 格納ファイルの属性 書庫固有 */ szMode As String * 8 ' /* 格納ファイルの格納モード 〃 */ End Type ' ハンドルと書庫ファイルを結び付けます。 Private Declare Function UnZipOpenArchive Lib "UnZip32.DLL" _ (ByVal hwnd As Long, _ ByVal szFilename As String, _ ByVal dwMode As Long) As Long ' UnZipOpenArchive() で割り付けたハンドルを解放する。 Private Declare Function UnZipCloseArchive Lib "UnZip32.DLL" _ (ByVal harc As Long) As Long ' 最初の格納ファイルの情報を得ます。 Private Declare Function UnZipFindFirst Lib "UnZip32.DLL" _ (ByVal harc As Long, _ ByVal szWildName As String, _ lpSubInfo As tagINDIVIDUALINFO) As Long ' 2番目以降の格納ファイルの情報を得ます。 Private Declare Function UnZipFindNext Lib "UnZip32.DLL" _ (ByVal harc As Long, _ lpSubInfo As tagINDIVIDUALINFO) As Long ' DOS形式の日付時間をFILETIMEに変換します。 Private Declare Function DosDateTimeToFileTime Lib "kernel32" _ (ByVal wFatDate As Long, _ ByVal wFatTime As Long, _ lpFileTime As Currency) As Long ' ローカル時刻は1601年1月1日以降のナノ秒で表される。 ' Currencyではミリ秒で表される。 ' 1日のミリ秒数で割り、1601年以降の日数を取得する。 ' 1601年から1899年までの日数を引き、VBの日数を計算する。 ' ' 10,000,000ナノ秒×60秒×60分×24時間÷10,000 = 86,4000,000 ' (10,000はCurrencyで固定小数点を調整する) ' ' VBの日付とWin32の日付の違い ' (#1899-12-30# - #1601-01-01#) Private Const conDayZeroBios As Double = 109205# Private Const conMillisecondPerDay As Double = 10000000# * 60# * 60# * 24# / 10000# ' ' 実際の使用にあたっては、書庫ファイルのデータは、 ' 配列かコレクションに格納したりして使います。 ' Private Sub Command1_Click() ' 変数の宣言 Dim udtINDIVIDUALINFO As tagINDIVIDUALINFO Dim udtFILETIME As Currency ' 構造体なんだけど通貨型で宣言 Dim strFileName As String ' 書庫ファイル名 Dim lngArcHandle As Long ' 書庫ファイルのハンドル Dim lngResult As Long ' APIの戻り値用 Dim strArcFileName As String ' 格納ファイル名 Dim lngArcFileOriginalSize As Long ' 格納ファイルのサイズ Dim lngArcFileCompressedSize As Long ' 格納ファイルの圧縮後のサイズ Dim sglArcFileRatio As Single ' 圧縮率 Dim dteArcFileDate As Date ' 格納ファイルの日時 Dim strArcFileAttr As String ' 格納ファイルの属性 Dim strArcFileType As String ' 格納ファイルの格納モード Dim lngArcFileCRC As Long ' 格納ファイルのチェックサム ' 書庫ファイル名を格納。 strFileName = "C:\My Documents\HEROPA\VBDeFM\vbdfm02f.zip" ' 書庫ファイルとハンドルを関連付ける。 lngArcHandle = UnZipOpenArchive(Me.hwnd, strFileName, 0) If lngArcHandle <> 0 Then ' 最初の書庫内のファイルの情報を取り出す。 If UnZipFindFirst(lngArcHandle, "*.*", udtINDIVIDUALINFO) = 0 Then Do ' ファイル名 strArcFileName = Left$(udtINDIVIDUALINFO.szFilename, InStr(udtINDIVIDUALINFO.szFilename, vbNullChar) - 1) ' ファイルのサイズ lngArcFileOriginalSize = udtINDIVIDUALINFO.dwOriginalSize ' 圧縮後のサイズ lngArcFileCompressedSize = udtINDIVIDUALINFO.dwCompressedSize ' 圧縮率 sglArcFileRatio = udtINDIVIDUALINFO.wRatio / 10 ' 格納ファイルの日付を取得する。 ' DOS形式の時間をFILETIMEに変換する。 lngResult = DosDateTimeToFileTime(CLng(udtINDIVIDUALINFO.wDate), CLng(udtINDIVIDUALINFO.wTime), udtFILETIME) ' FILETIMEをVBのDate型に変換する。 dteArcFileDate = CDate((udtFILETIME / conMillisecondPerDay) - conDayZeroBios) ' 属性 strArcFileAttr = Left$(udtINDIVIDUALINFO.szAttribute, InStr(udtINDIVIDUALINFO.szAttribute, vbNullChar) - 1) ' 格納ファイルの格納モード strArcFileType = Left$(udtINDIVIDUALINFO.szMode, InStr(udtINDIVIDUALINFO.szMode, vbNullChar) - 1) ' 格納ファイルのチェックサム lngArcFileCRC = udtINDIVIDUALINFO.dwCRC ' 結果をデバッグウィンドウに表示。 Debug.Print strArcFileName, _ lngArcFileOriginalSize, _ lngArcFileCompressedSize, _ Format$(sglArcFileRatio, "0.0") & "%", _ Format$(dteArcFileDate, "yyyy/mm/dd hh:nn:ss"), _ strArcFileAttr, _ strArcFileType, _ Right$("000000" & Hex$(lngArcFileCRC), 6) ' 次の格納ファイルの情報を取り出す。 Loop While UnZipFindNext(lngArcHandle, udtINDIVIDUALINFO) = 0 End If ' 書庫ファイルハンドルを閉じる。 lngResult = UnZipCloseArchive(lngArcHandle) End If End Sub
日付を変換する説明に関しては、「Lzh書庫内のファイルの情報を取り出す方法について」を参照してください。