|
-
Sep 9th, 2003, 10:21 AM
#1
Thread Starter
Lively Member
Bloody Structures - aaahhh
Hi all,
Does anyone know how vb.net works with structures when readin/writing them to files?
Im using a type that holds a string, which varies in length depending on a user's setup, along with other variables ie boolean.
Im getting bad record length when trying to read in a structure.
Does it write variable length records to the file, as Ive used UDT's in VB with no problems at all. Ive even tried to use fixed length strings( which vb.net doesnt support anyway).
Ive looked on the internet for any clues but theres nothing helpful.
Any help at all would be appreciated & stop me from pulling my hair out.
Thanks in advance.
-
Sep 9th, 2003, 11:29 AM
#2
I wonder how many charact
You haven't mentioned how you are saving your file. FileStream?
Anyway, please give some more detailed background information on how much data you want to save. Are these infrequent read/writes?
Tell us what your program is, what data its storing (start general, ie, person's name), and how big this project is.
.Net does serialization (saving of object data) like nobody's business. I suggest you learn how to use it.
A structure may be useful for small variables, but you really don't want to go through the trouble of writing routines for saving, updating records with data that is defined by a Structure.
The easiest thing to do is write a class that embodies the data you want to save, read and manipulate.
VB Code:
<Serializable()> Public Class Person
Public Sub New()
End Sub
Public Sub New(ByVal lFirstName As String, _
ByVal lLastName As String, ByVal lMember As Boolean)
pFirstName = lFirstName
pLastName = LastName
pMemberOfOurCompany = lMember
End Sub
Private pFirstName As String
Private pLastName As String
Private pMemberOfOurCompany As Boolean
Public Property FirstName() As String
Get
Return pFirstName
End Get
Set(ByVal Value As String)
Value = pFirstName
End Set
End Property
Public Property LastName() As String
Get
Return pLastName
End Get
Set(ByVal Value As String)
pLastName = Value
End Set
End Property
Public Property Member() As Boolean
Get
Return pMemberOfOurCompany
End Get
Set(ByVal Value As Boolean)
pMemberOfOurCompany = Value
End Set
End Property
Public Function GetFullName() As String
Return String.Concat(pFirstName, " ", pLastName)
End Function
'we can call the following function like so in code elsewhere
'Dim R as Person
'Dim FS as IO.FileStream("C:\mydata.ccc", FileModeOpen)
'R.Save(FS)
'Fs.Close
Public Function Save(ByRef lFS As IO.FileStream) As Boolean
Dim bs As System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
bs.Serialize(lFS, Me)
End Function
End Class
Now, that's a useful class, however, its really only good for storing one person object in a single file. If we save another Person object, it will simply overwrite the last object we saved to that file. You notice there is no load function either, well, there's a reason. The Save function I included is only for illustration, you should get rid of it.
Here's why:
To make this a practical class, you want to create another class that will allow you to store these items in a file. Below, is the class that creates a strongly-typed collection class for storing Person objects, and allows you to save them to disk.
VB Code:
<Serializable()> Public Class PersonCollection
Inherits System.Collections.CollectionBase
Default Public Property Item(ByVal index As Integer) As Person
Get
Return CType(Me.InnerList.Item(index), Person)
End Get
Set(ByVal Value As Person)
Me.InnerList.Item(index) = Value
End Set
End Property
Public Sub New()
End Sub
Public Function Add(ByVal lPerson As Person) As Integer
' Invokes Add method of the List object to add a object.
Return Me.InnerList.Add(lPerson)
End Function
Public Sub Remove(ByVal index As Integer)
If index > Count - 1 Or index < 0 Then
Else
' Invokes the RemoveAt method of the List object.
Dim sr As Person
sr = CType(Me.InnerList.Item(index), Person)
If Not sr Is Nothing Then
Me.InnerList.Remove(sr)
End If
Me.InnerList.RemoveAt(index)
End If
End Sub
Public Function SaveToStream(ByRef LFS As IO.FileStream) As Boolean
Dim bs As System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
bs.Serialize(LFS, Me)
End Function
Public Function LoadFromStream(ByRef lfs As IO.FileStream) As Boolean
Dim bs As System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim tempP As PersonCollection
Dim i As Integer
tempP = bs.Deserialize(lfs)
Me.InnerList.Clear()
For i = 0 To tempP.InnerList.Count - 1
Me.InnerList.Item(i) = tempP.InnerList.Item(i)
Next
End Function
End Class
Now, you can use code like the following to save your data...
VB Code:
'here's where we add some dummy data
Dim MyPersons As New PersonCollection
MyPersons.Add(New Person("Lydia","Manning",true)
MyPersons.Add(New Person("Steve","Brown",false)
'here's the saving part
Dim fs as filestream("C:\mytest.ccc",FileMode.OpenOrCreate)
MyPersons.Save(fs)
fs.Close
Last edited by nemaroller; Sep 9th, 2003 at 11:37 AM.
-
Sep 9th, 2003, 11:34 AM
#3
PowerPoster
Try doing some research on Serialization. Here is a quick example, I haven't tested this, but it *should* work
Code:
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace SerializeMe {
class MyExample {
static void Main(string[] args) {
FileStream stream = File.Open("example.dat", FileMode.OpenOrCreate);
BinaryFormatter f = new BinaryFormatter();
f.Serialize(stream, new FormSettings(100, 200));
stream.Close();
stream = File.OpenRead("example.dat");
FormSettings settings = (FormSettings)f.Deserialize(stream);
Console.WriteLine(String.Format("Width = {0} Height = {1}", settings.Width, settings.Height));
}
}
[Serializable()]
struct FormSettings {
public int Height;
public int Width;
public FormSettings(int height, int width) {
this.Height = height;
this.Width = width;
}
}
}
-
Sep 9th, 2003, 11:44 AM
#4
Thread Starter
Lively Member
Thanks to both of you for that.
nemaroller, Im just using the FileGet and FilePut to access the files. The files are read frequently, as they relate to the forms in the app that the user can see.
Im gona learn a bit more about serialization, and then start again.
Thanks
-
Sep 9th, 2003, 11:59 AM
#5
I wonder how many charact
http://www.devx.com/dotnet/Article/6971/0/page/1
Just so you are aware now... if you build your project, run some tests and save some data, then decide you need to change your class -- for example a property -- you might as well erase the data file on disk you were saving to (ie "C:\mytestdata.ccc"). If you don't, as soon as you rebuild your class and run your project again, your updated class will probably have problems reading the data file, and you will get a Deserialization error. Just like would happen if you added a new property to a UDT (and therefore changed its recordlength... you need to clear off your old data files)
Last edited by nemaroller; Sep 9th, 2003 at 12:04 PM.
-
Sep 9th, 2003, 12:00 PM
#6
Thread Starter
Lively Member
Thanks for that and thanks alot for the help you've given me.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|