Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
675 views
in Technique[技术] by (71.8m points)

vb.net - how to write to/read from a "settings" text file

I'm working on a Timer program, that allows the user to set up a timer for each individual user account on the computer. I'm having some trouble writing the settings to a text file and reading from it. I want to know if it's possible to write it in this fashion --> username; allowedTime; lastedLoggedIn; remainingTime; <-- in one line for each user, and how would I go about doing that? I also wanted to know if it's possible to alter the text file in this way, in the case that there's already an entry for a user, only change the allowedTime, or the remainingTime, kinda just updating the file?

Also I'm also having trouble being able to read from the text file. First of all I can't figure out how to determine if a selected user is in the file or not. Form there, if the user is listed in the file, how can access the rest of the line, like only get the allowedTime of that user, or the remaining time?

I tried a couple of ways, but i just can't get it to do how I'm imaging it, if that makes sense. here's the code so far:

Public Sub saveUserSetting(ByVal time As Integer)
    Dim hash As HashSet(Of String) = New HashSet(Of String)(File.ReadAllLines("Settings.txt"))
    Using w As StreamWriter = File.AppendText("Settings.txt")
        If Not hash.Contains(selectedUserName.ToString()) Then
            w.Write(selectedUserName + "; ")
            w.Write(CStr(time) + "; ")
            w.WriteLine(DateTime.Now.ToLongDateString() + "; ")
        Else
            w.Write(CStr(time) + "; ")
            w.WriteLine(DateTime.Now.ToLongDateString() + "; ")
        End If
    End Using
End Sub

Public Sub readUserSettings()
    Dim currentUser As String = GetUserName()
    Dim r As List(Of String) = New List(Of String)(System.IO.File.ReadLines("Settings.txt"))
    'For Each i = 0 to r.lenght - 1

    'Next
    'check to see if the current user is in the file
    MessageBox.Show(r(0).ToString())
    If r.Contains(selectedUserName) Then
        MessageBox.Show(selectedUserName + " is in the file.")
        'Dim allowedTime As Integer
    Else
        MessageBox.Show("the user is not in the file.")

    End If
    'if the name is in the file then
    'get the allowed time and the date
    'if the date is older than the current date return the allowed time
    'if the date = the current date then check thhe remaning time and return that
    'if the date is ahead of the current date return the reamining and display a messgae that the current date needs to be updated.
End Sub

edit: I just wanted to make sure if I'm doing the serialization right and the same for the deserialization. this is what i got so far:

Friend userList As New List(Of Users)

Public Sub saveUserSetting()
    Using fs As New System.IO.FileStream("Settings.xml", IO.FileMode.OpenOrCreate)
        Dim bf As New BinaryFormatter
        bf.Serialize(fs, userList)
    End Using
End Sub

Public Sub readUserSettings()
    Dim currentUser As String = GetUserName()
    Dim useList As New List(Of Users)
    Using fs As New System.IO.FileStream("Settings.xml", IO.FileMode.OpenOrCreate)
        Dim bf As New BinaryFormatter
        useList = bf.Deserialize(fs)
    End Using
    MessageBox.Show(useList(0).ToString)
End Sub

<Serializable>
Class Users
    Public userName As String
    Public Property allowedTime As Integer
    Public Property lastLoggedInDate As String
    Public Property remainingTime As Integer
    Public Overrides Function ToString() As String
        Return String.Format("{0} ({1}, {2}, {3})", userName, allowedTime, lastLoggedInDate, remainingTime)
    End Function
End Class

edit 2: I'm not too familiar with try/catch but would this work instead?

Public Sub readUserSettings()
    If System.IO.File.Exists("Settings") Then
        Using fs As New System.IO.FileStream("Settings", FileMode.Open, FileAccess.Read)
            Dim bf As New BinaryFormatter
            userList = bf.Deserialize(fs)
        End Using
    Else
        MessageBox.Show("The setting file doesn't exists.")
    End If
End Sub
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You have a few typos and such in your code, but it is pretty close for your first try:

Friend userList As New List(Of Users)

Public Sub saveUserSetting()
    ' NOTE: Using the BINARY formatter will write a binary file, not XML
    Using fs As New System.IO.FileStream("Settings.bin", IO.FileMode.OpenOrCreate)
        Dim bf As New BinaryFormatter
        bf.Serialize(fs, userList)
    End Using
End Sub

Public Sub readUserSettings()
    ' this doesnt seem needed:
    Dim currentUser As String = GetUserName()

    ' do not want the following line - it will create a NEW
    ' useRlist which exists only in this procedure
    ' you probably want to deserialize to the useRlist
    ' declared at the module/class level
    ' Dim useList As New List(Of Users)

    ' a) Check if the filename exists and just exit with an empty
    '    useRlist if not (like for the first time run).

    ' b) filemode wass wrong - never create here, just read
    Using fs As New System.IO.FileStream("Settings.bin", 
                 FileMode.Open, FileAccess.Read)
        Dim bf As New BinaryFormatter
        '  user list is declared above as useRList, no useList
        useList = bf.Deserialize(fs)
    End Using
    ' Console.WriteLine is much better for this
    MessageBox.Show(useList(0).ToString)
End Sub

<Serializable>
Class Users
    ' I would make this a property also
    Public userName As String
    Public Property allowedTime As Integer
    Public Property lastLoggedInDate As String
    Public Property remainingTime As Integer
    Public Overrides Function ToString() As String
        Return String.Format("{0} ({1}, {2}, {3})", userName, allowedTime, lastLoggedInDate, remainingTime)
    End Function
End Class

ToDo:

a) decide whether you want XML or binary saves. With XML, users can read/edit the file.

b) Use a file path created from Environment.GetFolder(); with a string literal it may end up in 'Program Files' when deployed, and you cannot write there.

c) when reading/loading the useRlist, use something like

FileStream(myUserFile, FileMode.Open, FileAccess.Read)

It wont exist the first time run, so check if it does and just leave the list empty. After that, you just need to open it for reading. For saving use something like:

 FileStream(myUserFile, FileMode.OpenOrCreate, FileAccess.Write)

You want to create it and write to it. You might put the Load/Save code inside a Try/Catch so if there are file access issues you can trap and report them, and so you know the list did not get saved or read.

Using a serializer, the entire contents of the list - no matter how long - will get saved with those 3-4 lines of code, and the entire list read back in the 2-3 lines to load/read the file.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...