读取用vb6编写的二进制文件 [英] Read Binary file written in vb6
问题描述
我在尝试制作的应用程序中遇到了障碍.
我正在尝试创建一个将读取二进制文件的应用程序.我正在使用binaryreader类.二进制文件是使用vb6中的put方法写入的.二进制文件中的数据将采用以下格式:
Hi,
I''ve come to a roadblock in an application I''m trying to make.
I''m trying to create an application that will read in a binary file. I''m using the binaryreader class. The binary file is written using the put method in vb6. The data inside the binary file will be in this form:
Private Type PlayerRec
' Account
Login As String * ACCOUNT_LENGTH
Password As String * NAME_LENGTH
' General
Name As String * ACCOUNT_LENGTH
Sex As Byte
Class As Long
Sprite As Long
Level As Byte
exp As Long
Access As Byte
PK As Byte
' Vitals
Vital(1 To Vitals.Vital_Count - 1) As Long
' Stats
Stat(1 To Stats.Stat_Count - 1) As Byte
POINTS As Long
' Worn equipment
Equipment(1 To Equipment.Equipment_Count - 1) As Long
' Inventory
Inv(1 To MAX_INV) As PlayerInvRec
Spell(1 To MAX_PLAYER_SPELLS) As Long
' Hotbar
Hotbar(1 To MAX_HOTBAR) As HotbarRec
' Position
Map As Long
x As Byte
y As Byte
Dir As Byte
End Type
我尝试在binaryreader中使用readstring()方法,但是它将在类型开头内的所有三个字符串中读取.我正在尝试将信息添加到不同的文本框中.
问题是,当我使用readstring()时,它将在一个文本框中填充"login","password"和"name".它们不是一次读取,而是一次全部读取.如何使它填充3个文本框而不是1个?
我现在只想开始阅读字符串.如果有人要我上传二进制文件,我会很高兴.
在此先感谢您.
I have tried to use the readstring() method in binaryreader but it would read in all three strings within the beginning of the type. I''m trying to add the info to different textboxes.
The problem is, when I use readstring(), it would populate one textbox with ''login'' ''password'' and ''name''. They are not read one at a time but all at once. How do I make it so it would populate 3 textboxes instead of 1?
I just want to start with reading the strings for now. If anyone wants me to upload the binary file, I''ll be more than happy to.
Thanks in advance.
推荐答案
您仍然可以在VB.NET中使用文件get和fileput等VB6代码(Option Explicit Off)
或者,如果您正在读取固定长度的文件,则可以使用一些代码来帮助您.
You can still use VB6 code such as fileget and fileput in VB.NET (Option Explicit Off)
or if you are reading fixed length files then some code to help you on your way.
Public Class RandomFile
Private fs As FileStream, sr As BinaryReader, sw As BinaryWriter
Private FieldString(), fpath As String
Private FieldCount, FieldPos(), FieldWidths(), FileLength, LineCount, LineWidth As Integer
Private Open As Boolean = True
Public Sub New(ByVal Path As String)
fpath = Path
If File.Exists(Path) Then
Dim f As New FileInfo(fpath)
FileLength = CInt(f.Length)
Else
FileLength = 0
End If
End Sub
Public Sub Dispose()
fs.Dispose()
End Sub
#Region " Properties "
Public ReadOnly Property Count() As Integer '' Number of records in file
Get
Return LineCount
End Get
End Property
Public Property Width() As Integer
Get
Return LineWidth
End Get
Set(ByVal value As Integer)
LineWidth = value
LineCount = FileLength \ LineWidth - 1 '' and total number of lines in file
End Set
End Property
Public ReadOnly Property Strings() As String()
Get
Return FieldString
End Get
End Property
Public WriteOnly Property Widths() As Integer()
Set(ByVal value As Integer())
FieldWidths = value '' set externally
FieldCount = UBound(FieldWidths) '' number of fields
ReDim FieldPos(FieldCount), FieldString(FieldCount) '' set the number of strings to be returned
LineWidth = 0 '' total length of a record
For i As Integer = 0 To FieldCount
FieldPos(i) = LineWidth '' start position of any field
LineWidth += FieldWidths(i) '' calculate file line width
Next
LineCount = FileLength \ LineWidth - 1 '' and total number of lines in file
End Set
End Property
#End Region
#Region " Read File "
Private Function ReadFieldBytes(ByVal Record As Integer, ByVal Index As Integer) As Byte()
fs = New FileStream(fpath, FileMode.Open, FileAccess.Read, FileShare.Read)
sr = New BinaryReader(fs)
fs.Seek(LineWidth * Record + FieldPos(Index), SeekOrigin.Begin)
Dim b() As Byte = sr.ReadBytes(FieldWidths(Index))
Return b
End Function
Private Function ReadFieldString(ByVal Record As Integer, ByVal Index As Integer) As String
Dim b() As Byte = ReadFieldBytes(Record, Index)
Dim s As String = ""
For i = 0 To UBound(b)
s &= Chr(b(i))
Next i
Return s
End Function
Public Function ReadBytes(ByVal Record As Integer) As Byte()
Try
fs = New FileStream(fpath, FileMode.Open, FileAccess.Read, FileShare.Read)
sr = New BinaryReader(fs)
fs.Seek(LineWidth * Record, SeekOrigin.Begin)
Dim b() As Byte = sr.ReadBytes(LineWidth) '' read length of each field
Return b '' close reader externally in case we want more
Catch ex As Exception
Return Nothing
End Try
End Function
Public Function ReadLine(Optional ByVal Record As Integer = 0) As String() '' read one line
Try
If Open Then
fs = New FileStream(fpath, FileMode.Open, FileAccess.Read, FileShare.Read)
sr = New BinaryReader(fs)
End If
fs.Seek(LineWidth * Record, SeekOrigin.Begin)
For Field As Integer = 0 To FieldCount '' read each field in turn
Dim b() As Byte = sr.ReadBytes(FieldWidths(Field)) '' read length of each field
FieldString(Field) = ""
For i = 0 To UBound(b)
FieldString(Field) &= Chr(b(i)) '' and convert it into string
Next i
Next Field
Open = False '' you may want to read more lines
Return FieldString '' close reader externally in case we want more
Catch ex As Exception
Return Nothing
End Try
End Function
Public Sub CloseReader()
sr.Close()
fs.Close()
fs.Dispose()
Open = True
End Sub
#End Region
#Region " Write File "
Public Function WriteField(ByVal Record As Integer, ByVal Index As Integer, ByVal Field() As String) As Boolean
Dim f As Integer = UBound(Field) '' length of array
Dim k As Integer = FieldWidths(Index) '' width of each line
Dim b(k * (f + 1) - 1) As Byte '' total number of bytes
For i As Integer = 0 To f
Dim s As String = Field(i).PadRight(k, cnBlank) '' Ensure string is width of field
For j = 0 To k - 1
b(i * k + j) = Asc(s.Substring(j)) '' convert string to bytes
Next
Next
Return WriteRecord(LineWidth * Record + FieldPos(Index), b) '' calculate start
End Function
Public Function WriteField(ByVal Record As Integer, ByVal Index As Integer, ByVal Field As String) As Boolean
Dim k As Integer = FieldWidths(Index) - 1
Field = Field.PadRight(k + 1, cnBlank) '' Ensure string is width of field
Dim b(k) As Byte '' and set bytes to match
For i As Integer = 0 To k
b(i) = Asc(Field.Substring(i)) '' convert string to bytes
Next
Return WriteRecord(LineWidth * Record + FieldPos(Index), b) '' calculate start
End Function
Public Function WriteField(ByVal Record As Integer, ByVal Offset As String, ByVal b() As Byte) As Boolean
Return WriteRecord(LineWidth * Record + Val(Offset), b) '' calculate start
End Function
Public Function WriteField(ByVal Record As Integer, ByVal Index As Integer, ByVal b() As Byte) As Boolean
Return WriteRecord(LineWidth * Record + FieldPos(Index), b) '' calculate start
End Function
Public Function WriteLine(ByVal Record As Integer, ByVal b() As Byte, Optional ByVal chk As Boolean = True) As Boolean
If chk Then
Return WriteRecord(LineWidth * Record, b) '' closes writer
Else
Try
If Open Then
fs = New FileStream(fpath, FileMode.Open, FileAccess.Write, FileShare.Write)
sw = New BinaryWriter(fs)
End If
fs.Seek(LineWidth * Record, SeekOrigin.Begin)
sw.Write(b)
sw.Flush()
Open = False
Return False
Catch ex As Exception
Debug.Print(ex.Message)
Return True
End Try
End If
End Function
Public Sub CloseWriter()
sw.Close()
fs.Close()
fs.Dispose()
Open = True
End Sub
Private Function WriteRecord(ByVal Start As Integer, ByVal b() As Byte) As Boolean
Try
fs = New FileStream(fpath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write)
sw = New BinaryWriter(fs)
fs.Seek(Start, SeekOrigin.Begin)
sw.Write(b)
sw.Flush()
sw.Close()
fs.Close()
fs.Dispose()
Return False
Catch ex As Exception
Debug.Print(ex.Message)
Return True
End Try
End Function '' check that file gets closed
#End Region
End Class
这可以通过读取字节数组中的文件来轻松完成.
this can be done easy with reading the file in a byte array.
这篇关于读取用vb6编写的二进制文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!