我正在使用定时器程序,该程序允许用户为计算机上的每个用户帐户设置计时器。我在将设置写入文本文件并从中读取时遇到了一些麻烦。我想知道是否有可能以这种方式编写它 - >用户名; allowedTime; lastedLoggedIn;剩余时间; < - 每个用户一行,我将如何做到这一点?我还想知道是否有可能以这种方式更改文本文件,如果已经有用户的条目,只更改allowedTime,或者剩余时间,有点只是更新文件?
此外,我也无法从文本文件中读取数据。首先,我无法弄清楚如何确定所选用户是否在文件中。在那里表单,如果文件中列出了用户,如何访问该行的其余部分,例如只获取该用户的allowedTime或剩余时间?
我尝试了几种方法,但如果有意义的话,我就无法做到如何对其进行成像。 这是迄今为止的代码:
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
编辑:我只是想确定我是否正确进行序列化以及反序列化。 这是我到目前为止所得到的:
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
编辑2: 我对try / catch不是很熟悉,但这会改变吗?
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
答案 0 :(得分:3)
你的代码中有一些拼写错误,但是你的第一次尝试非常接近:
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)决定是否需要XML或二进制保存。使用XML,用户可以读取/编辑文件。
b)使用从Environment.GetFolder()创建的文件路径;使用字符串文字,它可能最终会出现在&#39; Program Files&#39;部署时,你不能在那里写。
c)阅读/加载useRlist时,请使用类似
的内容FileStream(myUserFile, FileMode.Open, FileAccess.Read)
它不会在第一次运行时存在,因此检查它是否存在并将列表留空。之后,您只需打开它进行阅读即可。为了节省使用,例如:
FileStream(myUserFile, FileMode.OpenOrCreate, FileAccess.Write)
您想要创建并写入它。您可以将加载/保存代码放在Try / Catch中,这样如果存在文件访问问题,您可以捕获并报告它们,因此您知道列表未被保存或读取。
使用序列化程序,列表的全部内容 - 无论多长时间 - 将用这3-4行代码保存,整个列表在2-3行中读回以加载/读取文件。
答案 1 :(得分:0)
我没有得到你所有问题的答案,但我一直在研究计时器应用程序,最近才开始使用文本文件来读写信息。我使用的方法已证明其本身相当容易使用且不会令人困惑。以下是我的代码摘录:
Dim startup As String = "C:\Users\DigiParent\Desktop\Project data\Digitimeinfo.txt"
Dim reader As New System.IO.StreamReader(startup, Encoding.Default)
Dim data As String = reader.ReadToEnd
Dim aryTextFile(6) As String
aryTextFile = data.Split(",")
这将读取文本文件中的所有内容,并将它们之间的所有内容排序,并将它们单独存储在数组中。要将代码放回一行,请使用
Dim LineOfText As String
LineOfText = String.Join(",", aryTextFile)
所以你可以写这样的东西把你的信息写到文本文件中:
Dim startup As String = "C:\Users\DigiParent\Desktop\Project data\Digitimeinfo.txt"
Dim objWriter As New System.IO.StreamWriter(startup, False)
Dim aryTextFile(2) As String
aryTextFile(0) = pasword
aryTextFile(1) = user
aryTextFile(2) = remainingtime
LineOfText = String.Join(",", aryTextFile)
objWriter.WriteLine(LineOfText)
objWriter.Close()
并阅读它你可以使用蒸汽阅读器。