忍者ブログ

VB.NET-TIPS などプログラミングについて

VB.NETのTIPS(小技集)を中心に、Javascript、PHP その他のプログラミングについて少し役に立つ情報を発信します。いわゆる個人的な忘備録ですが、みなさんのお役に立てれば幸いです。

バイト配列を介したバイナリファイルの読込・書込処理について

バイナリファイルからのバイト配列への読込処理と、バイト配列からバイナリファイルへの書込処理について記します。 通常テキストファイルはバイナリファイルとは異なるものとして扱いますが、 ファイルの中身は文字コードのみで構成されたバイナリファイルとして取り扱いができます。 (データファイルは全てバイナリファイルであるとも言えますが)


■バイト配列からバイナリファイルへの書込処理

それではファイルを読込むためにファイルが存在しないと始まらないので、 バイナリファイルをバイト配列から書込む処理を説明します。
バイト配列は適当にデータを生成するとして、書込処理には System.IO.FileStream クラスの Write メソッドを使用します。

    Private Sub btnWrite_Click(sender As Object, e As EventArgs) Handles btnWrite.Click
        '書込むバイト型配列:Shift-JISの文字  "I"   "J"   "K"   "L"   "0"   "1"   "2"
        Dim arrByte As Byte() = New Byte() {&H49, &H4A, &H4B, &H4C, &H30, &H31, &H32}
        'ファイルを作成して書込む (存在する場合は上書き)
        Dim fs As New System.IO.FileStream("sample.txt", System.IO.FileMode.Create, System.IO.FileAccess.Write)
        'バイト型配列の内容をすべて書き込む 
        fs.Write(arrByte, 0, arrByte.Length)
        '閉じる 
        fs.Close()
    End Sub



■バイナリファイルからバイト配列への読込処理

バイナリファイルからの読込処理では最初に System.IO.FileStream クラスを生成することで対象ファイルをオープンします。 System.IO.FileStream クラスの長さのプロパティ Length 分のバイト配列を宣言し Read メソッドで読込を行います。

    Private Sub btnRead_Click(sender As Object, e As EventArgs) Handles btnRead.Click
        'ファイルを開く
        Dim fs As New System.IO.FileStream("sample.txt", System.IO.FileMode.Open, System.IO.FileAccess.Read)
        'ファイルを読み込むバイト型配列を作成
        Dim arrByte(fs.Length - 1) As Byte
        'ファイルの内容を全て読込
        fs.Read(arrByte, 0, arrByte.Length)
        'ファイルを閉じる
        fs.Close()
        'バイト配列を16進数表記の文字列で表示(各要素を「-」で連結)
        Console.WriteLine(BitConverter.ToString(arrByte))
    End Sub

実行結果がコンソールには以下様に表示されます。確かに書込み処理されたデータが読み込まれています。

49-4A-4B-4C-30-31-32



■大きなバイナリファイルの分割読込処理

上記の読込処理では System.IO.FileStream クラスでオープンした後でファイルの大きさでバイト配列を宣言しましたが、 ファイルサイズが非常に大きい場合、メモリ確保に負担が掛かります。 そのため以下の様に、固定のバイト数での読込を複数回処理することで全ての読込処理が行えます。

Read メソッドは順次読込を行いますが、ファイルの最後まで読込、更にこのメソッドを呼び出すと結果として「0」が返ります。 よって、「0」が返った時点で処理を終了します。

    Private Sub btnRead_Click(sender As Object, e As EventArgs) Handles btnRead.Click
        'ファイルを開く
        Dim fs As New System.IO.FileStream("sample.txt", System.IO.FileMode.Open, System.IO.FileAccess.Read)
        'ファイルを16バイトずつ読み込むバイト型配列を作成
        Dim arrByte(16 - 1) As Byte
        While True
            'ファイルの内容を全て読込
            Dim nRead As Integer = fs.Read(arrByte, 0, arrByte.Length)
            If nRead = 0 Then
                Exit While
            End If
            '部分読込データ処理

            'バイト配列を16進数表記の文字列で表示(各要素を「-」で連結)
            Console.WriteLine(BitConverter.ToString(arrByte))
        End While
        'ファイルを閉じる
        fs.Close()
    End Sub

実行結果がコンソールには以下様に表示されます。 書込まれているデータが7バイトのため、16バイト以下の読込となり1回で処理が終わることになります。

49-4A-4B-4C-30-31-32-00-00-00-00-00-00-00-00-00



■バイナリファイルのコピー処理

上記の分割読込処理を元にバイナリファイルコピーの処理を関数としてまとめてみました。

    ''' 
    ''' バイナリファイルコピー
    ''' 
    ''' <param name="SrcPath">コピー元のフルパスファイル名</param>
    ''' <param name="DesPath">コピー先のフルパスファイル名</param>
    ''' <param name="nSize">コピー分割処理バイト数</param>
    ''' True:正常終了, False:NG
    ''' エラーは詳細に処理していません
    Public Function CopyBinaryFile(ByVal SrcPath As String, ByVal DesPath As String, ByVal nSize As Integer) As Boolean
        CopyBinaryFile = True
        '読み書きの FileStream 宣言
        Dim fsRead As System.IO.FileStream = Nothing
        Dim fsWrite As System.IO.FileStream = Nothing
        Try
            '読込ファイルを開く
            fsRead = New System.IO.FileStream(SrcPath, System.IO.FileMode.Open, System.IO.FileAccess.Read)
            '書込ファイルを開く
            fsWrite = New System.IO.FileStream(DesPath, System.IO.FileMode.Create, System.IO.FileAccess.Write)
            'バイト配列宣言
            Dim arrByte = New Byte(nSize - 1) {}
            'コピー処理ループ
            While True
                '元のファイル読込
                Dim nRead As Integer = fsRead.Read(arrByte, 0, nSize)
                If nRead = 0 Then
                    Exit While
                End If
                'コピー先に書込 
                fsWrite.Write(arrByte, 0, nRead)
            End While

        Catch ex As Exception
            'エラー処理
            Return False
        Finally
            'ファイルクローズ
            If Not fsRead Is Nothing Then
                fsRead.Close()
            End If
            If Not fsWrite Is Nothing Then
                fsWrite.Close()
            End If
        End Try
    End Function

    'バイナリファイルコピーのテスト用ボタンクリック処理
    Private Sub btnCopy_Click(sender As Object, e As EventArgs) Handles btnCopy.Click
        Dim blnRet As Boolean = CopyBinaryFile("sample.txt", "sample2.txt", 4)
        Console.WriteLine("CopyBinaryFile...{0}", blnRet)
    End Sub

関連する記事

配列の使い方について(Dim, Redim)
配列の使い方の注意点について(コピー, Clone)











PR

コメント

コメントを書く