Adagio
Well-known member
- Joined
- Dec 12, 2005
- Messages
- 162
- Programming Experience
- Beginner
I have tried to create a method for writing information from an instance of a class to a binary file. The code works fine, the only problem is finding the end of the file. After it has read the last value that should be read, the basestream.Length is still higher than basestream.Position (by a random number)
In my case I have created a class with two fields (name and birthday), one that is string and a date field. With my code, this should write 5 lines to the file (classname + nameofNameField + StringValue + nameOfBirthdayField + DateValue)
When reading there's still more information in the file, when I have read the DateValue. Why? How do I find if it has read the end of the file?
In my case I have created a class with two fields (name and birthday), one that is string and a date field. With my code, this should write 5 lines to the file (classname + nameofNameField + StringValue + nameOfBirthdayField + DateValue)
When reading there's still more information in the file, when I have read the DateValue. Why? How do I find if it has read the end of the file?
VB.NET:
Imports System.Reflection
Imports System.IO
Public Module BugHunter
Public Sub Write(ByVal c As Object)
Dim fields As FieldInfo() = c.GetType.GetFields(BindingFlags.IgnoreCase Or BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.NonPublic)
Dim fs As System.IO.FileStream
Dim w As System.IO.BinaryWriter
' Opens or creates the file to write to
fs = New System.IO.FileStream("C:\Temp\test.cls", IO.FileMode.OpenOrCreate)
w = New System.IO.BinaryWriter(fs, System.Text.Encoding.UTF8)
w.Seek(0, System.IO.SeekOrigin.Begin)
' Writes class name
w.Write(c.GetType.FullName)
For Each f As FieldInfo In fields
' Gets the value of the field
Dim val As Object = f.GetValue(c)
' Writes the name of the field
w.Write(f.Name)
' If the value is of date, write number of ticks. Not possible to read date
If TypeOf val Is Date Then
Dim d As Date = DirectCast(f.GetValue(c), Date)
w.Write(d.Ticks)
Else
w.Write(f.GetValue(c))
End If
Next
' Close the file
w.Close()
fs.Close()
End Sub
Public Function Read() As Object
' Open file for reading
Dim f As New System.IO.FileStream("C:\Temp\test.cls", IO.FileMode.Open, IO.FileAccess.Read)
Dim reader As BinaryReader = New BinaryReader(f, System.Text.Encoding.UTF8)
' Gets type of class and create new instance
Dim nameOfClass As String = reader.ReadString
Dim obj As Object
obj = [Assembly].GetEntryAssembly.CreateInstance(nameOfClass)
' Read until end of file
While reader.BaseStream.Position < reader.BaseStream.Length
' Read field name
Dim nameOfField As String = reader.ReadString
' Get field info
Dim field As FieldInfo = obj.GetType.GetField(nameOfField, BindingFlags.IgnoreCase Or BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.NonPublic)
' Reads value based on field type
If field.FieldType Is GetType(String) Then
field.SetValue(obj, reader.ReadString)
ElseIf field.FieldType Is GetType(Date) Then
Dim tmp As Int64 = reader.ReadInt64()
field.SetValue(obj, New Date(tmp))
Else
MsgBox("Currently unsupported")
End If
End While
' Closes the file
f.Close()
reader.Close()
' Returns the new object
Return obj
End Function
End Module