Results 1 to 6 of 6

Thread: Bloody Structures - aaahhh

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Apr 2002
    Location
    Staffordshire
    Posts
    82

    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.

  2. #2
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704
    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:
    1. <Serializable()> Public Class Person
    2.     Public Sub New()
    3.  
    4.     End Sub
    5.  
    6.     Public Sub New(ByVal lFirstName As String, _
    7.     ByVal lLastName As String, ByVal lMember As Boolean)
    8.         pFirstName = lFirstName
    9.         pLastName = LastName
    10.         pMemberOfOurCompany = lMember
    11.     End Sub
    12.  
    13.     Private pFirstName As String
    14.     Private pLastName As String
    15.     Private pMemberOfOurCompany As Boolean
    16.  
    17.     Public Property FirstName() As String
    18.         Get
    19.             Return pFirstName
    20.         End Get
    21.         Set(ByVal Value As String)
    22.             Value = pFirstName
    23.  
    24.         End Set
    25.     End Property
    26.  
    27.     Public Property LastName() As String
    28.         Get
    29.             Return pLastName
    30.         End Get
    31.         Set(ByVal Value As String)
    32.             pLastName = Value
    33.  
    34.         End Set
    35.     End Property
    36.     Public Property Member() As Boolean
    37.         Get
    38.             Return pMemberOfOurCompany
    39.         End Get
    40.         Set(ByVal Value As Boolean)
    41.             pMemberOfOurCompany = Value
    42.  
    43.         End Set
    44.     End Property
    45.  
    46.     Public Function GetFullName() As String
    47.         Return String.Concat(pFirstName, " ", pLastName)
    48.     End Function
    49.  
    50.     'we can call the following function like so in code elsewhere
    51.     'Dim R as Person
    52.     'Dim FS as IO.FileStream("C:\mydata.ccc", FileModeOpen)
    53.     'R.Save(FS)
    54.     'Fs.Close
    55.     Public Function Save(ByRef lFS As IO.FileStream) As Boolean
    56.         Dim bs As System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
    57.         bs.Serialize(lFS, Me)
    58.     End Function
    59.  
    60. 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:
    1. <Serializable()> Public Class PersonCollection
    2.  
    3.     Inherits System.Collections.CollectionBase
    4.  
    5.     Default Public Property Item(ByVal index As Integer) As Person
    6.         Get
    7.             Return CType(Me.InnerList.Item(index), Person)
    8.         End Get
    9.         Set(ByVal Value As Person)
    10.             Me.InnerList.Item(index) = Value
    11.  
    12.         End Set
    13.     End Property
    14.  
    15.  
    16.  
    17.     Public Sub New()
    18.  
    19.     End Sub
    20.  
    21.     Public Function Add(ByVal lPerson As Person) As Integer
    22.         ' Invokes Add method of the List object to add a object.
    23.         Return Me.InnerList.Add(lPerson)
    24.  
    25.     End Function
    26.  
    27.  
    28.     Public Sub Remove(ByVal index As Integer)
    29.  
    30.         If index > Count - 1 Or index < 0 Then
    31.  
    32.         Else
    33.             ' Invokes the RemoveAt method of the List object.
    34.             Dim sr As Person
    35.  
    36.             sr = CType(Me.InnerList.Item(index), Person)
    37.             If Not sr Is Nothing Then
    38.                 Me.InnerList.Remove(sr)
    39.             End If
    40.             Me.InnerList.RemoveAt(index)
    41.         End If
    42.     End Sub
    43.  
    44.     Public Function SaveToStream(ByRef LFS As IO.FileStream) As Boolean
    45.         Dim bs As System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
    46.         bs.Serialize(LFS, Me)
    47.     End Function
    48.  
    49.     Public Function LoadFromStream(ByRef lfs As IO.FileStream) As Boolean
    50.         Dim bs As System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
    51.         Dim tempP As PersonCollection
    52.         Dim i As Integer
    53.         tempP = bs.Deserialize(lfs)
    54.         Me.InnerList.Clear()
    55.         For i = 0 To tempP.InnerList.Count - 1
    56.             Me.InnerList.Item(i) = tempP.InnerList.Item(i)
    57.         Next
    58.     End Function
    59. End Class

    Now, you can use code like the following to save your data...
    VB Code:
    1. 'here's where we add some dummy data
    2. Dim MyPersons As New PersonCollection
    3. MyPersons.Add(New Person("Lydia","Manning",true)
    4. MyPersons.Add(New Person("Steve","Brown",false)
    5.  
    6. 'here's the saving part
    7.  
    8. Dim fs as filestream("C:\mytest.ccc",FileMode.OpenOrCreate)
    9. MyPersons.Save(fs)
    10. fs.Close
    Last edited by nemaroller; Sep 9th, 2003 at 11:37 AM.

  3. #3
    PowerPoster Lethal's Avatar
    Join Date
    Oct 2000
    Location
    Ohio
    Posts
    2,496
    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;
            }
    }
    }

  4. #4

    Thread Starter
    Lively Member
    Join Date
    Apr 2002
    Location
    Staffordshire
    Posts
    82
    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

  5. #5
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704
    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.

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Apr 2002
    Location
    Staffordshire
    Posts
    82
    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
  •  



Click Here to Expand Forum to Full Width