NonSoft

バイナリファイルを比較し差分を表示するサンプル(VB6)


 サンプル(ソース/コード)
<このサンプルの概要>
バイナリファイルを比較し差分を分かりやすく表示するサンプル(VB6)です。

バイナリ差分表示結果の例
----------------------------------------------------------------------------
区分 NO file1                            NO file2
      1 31323334353637383930313233343536  1 31323334353637383930313233343536
変更  2 4142434445464748494A4B4C4D4E4F50  2 4142434445464720494A4B4C4D4E4F50
追加                                      3 6162636465666768696A6B6C6D6E6F70
----------------------------------------------------------------------------

処理の流れは以下の流れです。
1.バイナリファイル読み込み
2.バイナリデータを16進文字列に変換
3.バイナリ差分解析
4.バイナリ差分表示)

差分表示する必要が無い時(バイナリ比較のみ)は下の方にあるサンプルをご覧ください。
バイナリファイルを比較するだけのサンプル

VB.NET版はこちら「バイナリファイルを比較し差分を表示するサンプル(VB.NET)」です。
C#.NET版はこちら「バイナリファイルを比較し差分を表示するサンプル(C#.NET)」です。

2G以上のファイルの場合はこちら「2G以上の大きなファイルを比較するサンプル(VB6)」です。

バイナリファイルの比較が出来るツールがありますので紹介します。
テキスト差分表示ツールはテキストを比較するツールですがバイナリも比較出来ます。

ファイル比較関係のその他のツールやサンプルソースはこちらです。
ファイル比較/フォルダ比較

★2つのバイナリファイルを比較し差分をデバッグ出力するサンプル
' 2つのバイナリファイルを比較し差分をデバッグ出力するサンプル
' バイナリ差分表示結果の例
' 区分 NO file1                            NO file2
'       1 31323334353637383930313233343536  1 31323334353637383930313233343536
' 変更  2 4142434445464748494A4B4C4D4E4F50  2 4142434445464720494A4B4C4D4E4F50
' 追加                                      3 6162636465666768696A6B6C6D6E6F70
Private Sub Command1_Click()
    ' バイナリファイル読み込み
    Dim bytDt1() As Byte
    Dim bytDt2() As Byte
    bytDt1 = ByteRead("D:\Temp\Test1.txt")
    bytDt2 = ByteRead("D:\Temp\Test2.txt")

    ' バイナリデータを16進文字列に変換
    Dim strDt1 As String
    Dim strDt2 As String
    strDt1 = ByteToString(bytDt1)
    strDt2 = ByteToString(bytDt2)

    ' 16進文字列を行単位の配列に変換
    Dim strAr1() As String
    Dim strAr2() As String
    If Right$(strDt1, 2) = vbCrLf Then strDt1 = Left$(strDt1, Len(strDt1) - 2)
    strAr1 = Split(strDt1, vbCrLf)
    If Right$(strDt2, 2) = vbCrLf Then strDt2 = Left$(strDt2, Len(strDt2) - 2)
    strAr2 = Split(strDt2, vbCrLf)
    
    ' バイナリ差分解析
    Dim num As Long: num = UBound(strAr1) + 1
    If num < UBound(strAr2) + 1 Then num = UBound(strAr2) + 1
    Dim dfList() As String
    ReDim dfList(4, num)
    dfList(0, 0) = "区分"
    dfList(1, 0) = "NO"
    dfList(2, 0) = "file1"
    dfList(3, 0) = "NO"
    dfList(4, 0) = "file2"
    Dim i As Long
    For i = 1 To num
        If i - 1 <= UBound(strAr1) Then
            dfList(1, i) = i
            dfList(2, i) = strAr1(i - 1)
        End If
        If i - 1 <= UBound(strAr2) Then
            dfList(3, i) = i
            dfList(4, i) = strAr2(i - 1)
        End If
        If dfList(2, i) = "" And dfList(4, i) <> "" Then
            dfList(0, i) = "追加"
        ElseIf dfList(2, i) <> "" And dfList(4, i) = "" Then
            dfList(0, i) = "削除"
        ElseIf dfList(2, i) <> dfList(4, i) Then
            dfList(0, i) = "変更"
        End If
    Next i
    
    ' バイナリ差分表示
    For i = 0 To UBound(dfList, 2)
        Debug.Print dfList(0, i) & vbTab & _
                    dfList(1, i) & vbTab & dfList(2, i) & vbTab & _
                    dfList(3, i) & vbTab & dfList(4, i)
    Next i
End Sub

' バイナリファイル読み込み
Private Function ByteRead(ByVal fPath As String) As Byte()
    Dim bytDt() As Byte
    ReDim bytDt(-1 To -1)
    If FileLen(fPath) > 0 Then
        ReDim bytDt(FileLen(fPath) - 1) As Byte
        Dim intFNo As Integer: intFNo = FreeFile
        Open fPath For Binary As intFNo
        Get intFNo, , bytDt
        Close
    End If
    ByteRead = bytDt
End Function

' バイナリデータを16進文字列に変換
Public Function ByteToString(ByRef bytDt() As Byte) As String
    Const LBYT = 16
    Dim lins As Long: lins = Int((UBound(bytDt) + 1) / LBYT)
    Dim byts As Long: byts = (UBound(bytDt) + 1) Mod LBYT
    ByteToString = String$((lins * (LBYT + 1) * 2) + (byts * 2), Chr(0))
    Dim l As Long: l = 0
    Dim i As Long
    For i = 0 To UBound(bytDt)
        Dim ival As Integer: ival = bytDt(i)
        Dim sval As String
        If ival < 16 Then
            sval = "0" & Hex(ival)
        Else
            sval = Hex(ival)
        End If
        Mid$(ByteToString, (l * (LBYT + 1) * 2) + ((i Mod LBYT) * 2) + 1, 2) = sval
        
        If ((i + 1) Mod LBYT) <> 0 Then
        Else
            Mid$(ByteToString, (l * (LBYT + 1) * 2) + ((i Mod LBYT) * 2) + 1 + 2, 2) = vbCrLf
            l = l + 1
        End If
    Next i
End Function

★2つのバイナリファイルを比較するだけのサンプル
Private Sub Command1_Click()
    Dim fpath1 As String: fpath1 = "D:\Temp\Test1.txt"
    Dim fpath2 As String: fpath2 = "D:\Temp\Test2.txt"
    If FileLen(fpath1) <> FileLen(fpath2) Then
        MsgBox "不一致"
        Exit Sub
    End If
    
    Dim bytDt1(0) As Byte
    Dim bytDt2(0) As Byte
    Dim intFn1 As Integer: intFn1 = 1
    Dim intFn2 As Integer: intFn2 = 2
    Open fpath1 For Binary As intFn1
    Open fpath2 For Binary As intFn2
    
    Dim dif As Boolean: dif = False
    Dim p As Long: p = 1
    Do While Not (EOF(intFn1) Or EOF(intFn2))
        Get intFn1, p, bytDt1
        Get intFn2, p, bytDt2
        p = p + 1
        ' バイナリデータを比較
        If bytDt1(0) <> bytDt2(0) Then
            dif = True
            Exit Do
        End If
    Loop
    
    Close intFn1
    Close intFn2
    
    If dif Then
        MsgBox "バイナリ不一致"
    Else
        MsgBox "バイナリ一致"
    End If
End Sub