(VB.NET)SHIFT‐JISでエンコードされたバイナリデータファイルを作成するコードについて - tsukimisoba/Blog GitHub Wiki
2025/06/20
Imports System.IO
Imports System.Text
Public Class PersonData
Public Property Name As String
Public Property Age As Integer
Public Sub New()
Name = ""
Age = 0
End Sub
Public Sub New(name As String, age As Integer)
Me.Name = name
Me.Age = age
End Sub
End Class
Public Class BinaryFileHandler
Private Const NAME_SIZE As Integer = 10
Private Const AGE_SIZE As Integer = 4
Private Const RECORD_SIZE As Integer = NAME_SIZE + AGE_SIZE
Private Shared ReadOnly shiftJisEncoding As Encoding = Encoding.GetEncoding("shift_jis")
''' <summary>
''' バイナリファイルにデータを書き込む
''' </summary>
''' <param name="filePath">ファイルパス</param>
''' <param name="persons">書き込むPersonDataのリスト</param>
Public Shared Sub WriteToFile(filePath As String, persons As List(Of PersonData))
Using fs As New FileStream(filePath, FileMode.Create, FileAccess.Write)
Using bw As New BinaryWriter(fs)
For Each person In persons
WritePersonData(bw, person)
Next
End Using
End Using
End Sub
''' <summary>
''' バイナリファイルからデータを読み込む
''' </summary>
''' <param name="filePath">ファイルパス</param>
''' <returns>読み込んだPersonDataのリスト</returns>
Public Shared Function ReadFromFile(filePath As String) As List(Of PersonData)
Dim persons As New List(Of PersonData)()
Using fs As New FileStream(filePath, FileMode.Open, FileAccess.Read)
Using br As New BinaryReader(fs)
While fs.Position < fs.Length
Dim person As PersonData = ReadPersonData(br)
persons.Add(person)
End While
End Using
End Using
Return persons
End Function
''' <summary>
''' 1レコード分のPersonDataを書き込む
''' </summary>
''' <param name="writer">BinaryWriter</param>
''' <param name="person">書き込むPersonData</param>
Private Shared Sub WritePersonData(writer As BinaryWriter, person As PersonData)
' 氏名(10バイト固定)
Dim nameBytes As Byte() = GetFixedLengthBytes(person.Name, NAME_SIZE)
writer.Write(nameBytes)
' 年齢(4バイト Integer)
writer.Write(person.Age)
End Sub
''' <summary>
''' 1レコード分のPersonDataを読み込む
''' </summary>
''' <param name="reader">BinaryReader</param>
''' <returns>読み込んだPersonData</returns>
Private Shared Function ReadPersonData(reader As BinaryReader) As PersonData
' 氏名(10バイト)を読み込み
Dim nameBytes As Byte() = reader.ReadBytes(NAME_SIZE)
Dim name As String = GetStringFromBytes(nameBytes)
' 年齢(4バイト)を読み込み
Dim age As Integer = reader.ReadInt32()
Return New PersonData(name, age)
End Function
''' <summary>
''' 文字列を指定バイト数のSHIFT-JISバイト配列に変換(固定長)
''' </summary>
''' <param name="text">変換する文字列</param>
''' <param name="fixedLength">固定バイト数</param>
''' <returns>固定長のバイト配列</returns>
Private Shared Function GetFixedLengthBytes(text As String, fixedLength As Integer) As Byte()
Dim result As Byte() = New Byte(fixedLength - 1) {}
If Not String.IsNullOrEmpty(text) Then
Dim textBytes As Byte() = shiftJisEncoding.GetBytes(text)
Dim copyLength As Integer = Math.Min(textBytes.Length, fixedLength)
Array.Copy(textBytes, result, copyLength)
End If
' 残りの部分は0で埋められる(初期化時に0で初期化済み)
Return result
End Function
''' <summary>
''' SHIFT-JISバイト配列から文字列に変換
''' </summary>
''' <param name="bytes">バイト配列</param>
''' <returns>変換された文字列</returns>
Private Shared Function GetStringFromBytes(bytes As Byte()) As String
' 末尾の0バイトを除去
Dim endIndex As Integer = Array.IndexOf(bytes, CByte(0))
If endIndex = -1 Then
endIndex = bytes.Length
End If
If endIndex = 0 Then
Return String.Empty
End If
Return shiftJisEncoding.GetString(bytes, 0, endIndex)
End Function
End Class
' 使用例
Public Class Program
Public Shared Sub Main()
' テストデータ作成
Dim persons As New List(Of PersonData) From {
New PersonData("田中太郎", 25),
New PersonData("佐藤花子", 30),
New PersonData("山田次郎", 35)
}
Dim filePath As String = "persons.dat"
Try
' ファイルに書き込み
Console.WriteLine("データをファイルに書き込み中...")
BinaryFileHandler.WriteToFile(filePath, persons)
Console.WriteLine("書き込み完了")
' ファイルから読み込み
Console.WriteLine("ファイルからデータを読み込み中...")
Dim readPersons As List(Of PersonData) = BinaryFileHandler.ReadFromFile(filePath)
Console.WriteLine("読み込み完了")
' 読み込んだデータを表示
Console.WriteLine("読み込んだデータ:")
For Each person In readPersons
Console.WriteLine($"氏名: {person.Name}, 年齢: {person.Age}")
Next
Catch ex As Exception
Console.WriteLine($"エラーが発生しました: {ex.Message}")
End Try
Console.WriteLine("何かキーを押してください...")
Console.ReadKey()
End Sub
End Class