NonSoft

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


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

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

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

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

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

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

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

★2つのバイナリファイルを比較し差分をデバッグ出力するサンプル
' 2つのバイナリファイルを比較し差分をデバッグ出力するサンプル
' バイナリ差分表示結果の例
' 区分 NO file1                            NO file2
'       1 31323334353637383930313233343536  1 31323334353637383930313233343536
' 変更  2 4142434445464748494A4B4C4D4E4F50  2 4142434445464720494A4B4C4D4E4F50
' 追加                                      3 6162636465666768696A6B6C6D6E6F70
Private Sub Button1_Click( _
    ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles Button1.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 strDt1.Substring(strDt1.Length - 2, 2) = vbCrLf Then
        strDt1 = strDt1.Substring(0, strDt1.Length - 2)
    End If
    strAr1 = Split(strDt1, vbCrLf)
    If strDt2.Substring(strDt2.Length - 2, 2) = vbCrLf Then
        strDt2 = strDt2.Substring(0, strDt2.Length - 2)
    End If
    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 dt As Byte() = New Byte() {}
    Dim sr As System.IO.Stream = Nothing
    Dim br As System.IO.BinaryReader = Nothing
    sr = System.IO.File.Open(fPath, _
        System.IO.FileMode.Open, _
        System.IO.FileAccess.Read)
    br = New System.IO.BinaryReader(sr)
    dt = New Byte(sr.Length - 1) {}
    br.Read(dt, 0, dt.Length)
    br.Close()
    sr.Close()
    Return dt
End Function

' バイナリデータを16進文字列に変換
Public Function ByteToString(ByRef bytDt() As Byte) As String
    Const LBYT = 16
    Dim sb As New System.Text.StringBuilder("")
    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
        sb.Append(sval)

        If ((i + 1) Mod LBYT) <> 0 Then
        Else
            sb.Append(vbCrLf)
        End If
    Next i
    Return sb.ToString()
End Function

★2つのバイナリファイルを比較するだけのサンプル
Private Sub Button1_Click( _
    ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles Button1.Click

    Dim fpath1 As String : fpath1 = "D:\Temp\Test1.txt"
    Dim fpath2 As String : fpath2 = "D:\Temp\Test2.txt"
    Dim f1 As New System.IO.FileInfo(fpath1)
    Dim f2 As New System.IO.FileInfo(fpath2)
    If f1.Length <> f2.Length Then
        MsgBox("不一致")
        Exit Sub
    End If

    Dim sr1 As System.IO.Stream = Nothing
    Dim sr2 As System.IO.Stream = Nothing
    Dim br1 As System.IO.BinaryReader = Nothing
    Dim br2 As System.IO.BinaryReader = Nothing
    sr1 = System.IO.File.Open(fpath1, _
        System.IO.FileMode.Open, _
        System.IO.FileAccess.Read)
    sr2 = System.IO.File.Open(fpath2, _
        System.IO.FileMode.Open, _
        System.IO.FileAccess.Read)
    br1 = New System.IO.BinaryReader(sr1)
    br2 = New System.IO.BinaryReader(sr2)

    Dim dif As Boolean : dif = False
    Do
        Dim bytDt1 As Integer
        Dim bytDt2 As Integer
        bytDt1 = sr1.ReadByte()
        bytDt2 = sr2.ReadByte()
        ' バイナリデータを比較
        If bytDt1 <> bytDt2 Then
            dif = True
            Exit Do
        End If
        If bytDt1 = -1 Then Exit Do
    Loop

    br1.Close()
    br2.Close()
    sr1.Close()
    sr2.Close()

    If dif Then
        MsgBox("バイナリデータ不一致")
    Else
        MsgBox("バイナリデータ一致")
    End If
End Sub