Author | Message | Time |
---|---|---|
Zer0 | Ok i was wondering if i could get some ideas or feedback or somthn from my user managment system, there is one part i know i could do better but im not sure how to do it, so some ideas please... [code] Public Function userAdd(ByVal userName As String, ByVal userAcces As String, ByVal userAddedBy As String) As String If userName <> "" And userAcces <> "" And userAddedBy <> "" Then If File.Exists(App_Path() + "/users/" + userName + ".txt") = True Then 'user exists (update user) Dim oRead As System.IO.StreamReader Dim oFile As System.IO.File Dim oWrite As System.IO.StreamWriter = oFile.CreateText(App_Path() + "/users/" + userName + ".txt") oWrite.WriteLine("Username=" & userName) oWrite.WriteLine("Acces=" & userAcces) oWrite.WriteLine("AddedBy=" & userAddedBy) oWrite.Close() Return "User updated [ " + userName + " ] added with acces [ " + userAcces + " ]" Else 'user doesnt exist Dim fs As New FileStream(App_Path() + "/users/" + userName + ".txt", FileMode.Create, FileAccess.Write) fs.Close() Dim oRead As System.IO.StreamReader Dim oFile As System.IO.File Dim oWrite As System.IO.StreamWriter = oFile.CreateText(App_Path() + "/users/" + userName + ".txt") oWrite.WriteLine("Username=" & userName) oWrite.WriteLine("Acces=" & userAcces) oWrite.WriteLine("AddedBy=" & userAddedBy) oWrite.Close() Return "User [ " + userName + " ] added with acces [ " + userAcces + " ]" End If Else Return "Information In Unacceptable Format. Correct Format: [username] [userlevel]" End If End Function Public Function userDel(ByVal userName As String) As String If File.Exists(App_Path() + "/users/" + userName + ".txt") = True Then System.IO.File.Delete(App_Path() + "/users/" + userName + ".txt") Return "User [ " + userName + " ] removed from database." Else Return "User [ " + userName + " ] was not found in the database." End If End Function Public Function userFind(ByVal userName As String) As String If File.Exists(App_Path() + "/users/" + userName + ".txt") = True Then Dim oRead As System.IO.StreamReader Dim oFile As System.IO.File Dim a() As String Dim LineIn As String Dim userAcces As String Dim userAddedBy As String oRead = oFile.OpenText(App_Path() + "/users/" + userName + ".txt") While oRead.Peek <> -1 LineIn = oRead.ReadLine() a = LineIn.Split("=") If a(0) = "Username" Then userName = a(1) End If If a(0) = "Acces" Then userAcces = a(1) End If If a(0) = "AddedBy" Then userAddedBy = a(1) End If End While Return "User [" + userName + "] with acces of [" + userAcces + "], user was added by [" + userAddedBy + "]" oRead.Close() Else Return "User not found in database." End If End Function [/code] here is the part i know could be done better (it is in the above code) [code] 'user doesnt exist Dim fs As New FileStream(App_Path() + "/users/" + userName + ".txt", FileMode.Create, FileAccess.Write) fs.Close() Dim oRead As System.IO.StreamReader Dim oFile As System.IO.File Dim oWrite As System.IO.StreamWriter = oFile.CreateText(App_Path() + "/users/" + userName + ".txt") [/code] | October 5, 2006, 6:27 PM |
rabbit | You should store all the info in an array (using a Type declaration), and only access the file at certain times (IE: load on run, save on close, load/save on demand). That would greatly improve the speed (I mean noticeably too, not by .02ms or something). | October 5, 2006, 7:22 PM |
Zer0 | let me just make sure i am understanding u right so Program Starts -> Load Users Into Array -edit question removed, answered on aim Program Ends -> Save Array Back into Files also can anyone help me with the save on close part ;D | October 5, 2006, 7:26 PM |
Myndfyr | [quote author=Zer0 link=topic=15825.msg159458#msg159458 date=1160076406] also can anyone help me with the save on close part ;D [/quote] Yes. When the program ends (Form.Closing event of your main Form), do the same thing you do when you have a save-on-demand. | October 5, 2006, 9:01 PM |
indulgence | I would have created my user object, created a typed collection for the user object, marked both serializable, and serialized the user collection to file.. Serialization/Deserialization is much cleaner than the code to read - parse - proceed... [code] Namespace Management <Serializable()> Public Class User Public Name As String Public Password As String <XmlIgnore()> Public hash As New System.Security.Cryptography.HMACSHA1(System.Text.ASCIIEncoding.ASCII.GetBytes("mykey")) Public Sub New() End Sub Public Sub New(ByVal _Name As String, ByVal _Password As String) Name = _Name Password = _Password End Sub Public Function Validate(ByVal ClearTextPW As String) As Boolean Return GetPasswordHash(ClearTextPW).Equals(Password) End Function Public Function SetPassword(ByVal CleartextOldPW As String, ByVal CleartextNewPW As String) As Boolean If Validate(CleartextOldPW) Then Password = GetPasswordHash(CleartextNewPW) Return True End If Return False End Function Private Function GetPasswordHash(ByVal ClearTextPW As String) As String Return BitConverter.ToString(hash.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(ClearTextPW))) End Function End Class <Serializable()> Public Class UserCollection Inherits CollectionBase Private _Serializer As XmlSerializer = New System.Xml.Serialization.XmlSerializer(GetType(UserCollection)) Default Public Property Items(ByVal index As Integer) As User Get If index >= 0 And index < list.Count Then Return DirectCast(List(index), User) End Get Set(ByVal Value As User) If index >= 0 And index < list.Count Then list(index) = Value End Set End Property Default Public Property Items(ByVal Name As String) As User Get Dim index As Integer = Me.IndexOf(Name) If Not index < 0 Then Return DirectCast(List(index), User) End Get Set(ByVal Value As User) Dim index As Integer = Me.IndexOf(Name) If Not index < 0 Then list(index) = Value End Set End Property Public Overloads Function Equals(ByVal Users As UserCollection) As Boolean If Not Users.Count = list.Count Then Return False For index As Integer = 0 To List.Count - 1 If Not Users(index).Equals(Me(index)) Then Return False Next Return True End Function Public Function Add(ByVal Item As User) As Integer If Not Me.Contains(Item) Then Return list.Add(Item) End Function Public Function Contains(ByVal Item As User) As Boolean Return list.Contains(Item) End Function Public Sub CopyTo(ByVal Array As User(), ByVal index As Integer) list.CopyTo(Array, index) End Sub Public Sub CopyTo(ByVal Array As IList, ByVal index As Integer) For Each item As User In Me.List Array.Add(item) Next End Sub Public Function IndexOf(ByVal Item As User) As Integer Return list.IndexOf(Item) End Function Public Function IndexOf(ByVal Name As String) As Integer For index As Integer = 0 To list.Count - 1 If Name.ToLower.Equals(Me(index).Name.ToLower) Then Return index End If Next Return -1 End Function Public Sub Insert(ByVal Index As Integer, ByVal Item As User) list.Insert(Index, Item) End Sub Public Sub Remove(ByVal Item As User) list.Remove(Item) End Sub Public Sub Remove(ByVal Name As String) For index As Integer = 0 To list.Count - 1 If Me(index).Name.Equals(Name) Then list.RemoveAt(index) Exit For End If Next End Sub Public Function Save(ByVal Path As String) As Boolean Dim fs As IO.FileStream Try IO.File.Copy(Path, Path & ".bak") fs = IO.File.Open(Path, IO.FileMode.Truncate, IO.FileAccess.Write) _Serializer.Serialize(fs, Me) IO.File.Delete(Path & ".bak") fs.Close() Catch fs.Close() IO.File.Delete(Path) IO.File.Move(Path & ".bak", Path) End Try Return True End Function Public Sub New(ByVal Path As String) Dim fs As IO.FileStream Try fs = IO.File.Open(Path, IO.FileMode.Open, IO.FileAccess.Read) Dim lc As UserCollection = _Serializer.Deserialize(fs) lc.CopyTo(Me.List, 0) Finally fs.Close() End Try End Sub Public Sub New() End Sub End Class End Namespace [/code] It's long - but you can edit users, add user, delete users from the UserCollection, and call the save method to save it... [you'd want to update the save routine to meet your specs for the filename etc...] and by calling the overloaded new on UserCollection it will deserialize the file into a collection of your user objects. XML ftw? | November 16, 2006, 6:07 AM |
Myndfyr | While I don't disagree, you can serialize List<T> into XML as long as you provide a root node name in metadata.... I have to look through my test projects at work, it's possible. Then you just pass the List<User> into the XML serializer. However, I disagree on the use of the serialization framework. XML is probably not so much an evildoer in this instance, but for sure the binary formatter does not emit version-flexible output. Doing custom serialization as far as custom output or even writing custom XML files is FAR more flexible than trusting it to the serialization framework. | November 16, 2006, 6:37 AM |
indulgence | [quote author=MyndFyre[vL] link=topic=15825.msg161265#msg161265 date=1163659043] However, I disagree on the use of the serialization framework. XML is probably not so much an evildoer in this instance, but for sure the binary formatter does not emit version-flexible output. Doing custom serialization as far as custom output or even writing custom XML files is FAR more flexible than trusting it to the serialization framework. [/quote] True, but not as simple, nor as quick. The inability to (de)serialize DateTime objects is the killer - and you have to hack in a timespan and convert it | November 16, 2006, 5:40 PM |
Myndfyr | [quote author=indulgence link=topic=15825.msg161284#msg161284 date=1163698825] [quote author=MyndFyre[vL] link=topic=15825.msg161265#msg161265 date=1163659043] However, I disagree on the use of the serialization framework. XML is probably not so much an evildoer in this instance, but for sure the binary formatter does not emit version-flexible output. Doing custom serialization as far as custom output or even writing custom XML files is FAR more flexible than trusting it to the serialization framework. [/quote] True, but not as simple, nor as quick. The inability to (de)serialize DateTime objects is the killer - and you have to hack in a timespan and convert it [/quote] What? DateTime is serializable. You can also do custom serialization via using DateTime.FromFileTime and DateTime.ToFileTime(). | November 17, 2006, 6:32 AM |