要使用序列化保留多个条目的登录记录,您需要序列化对象列表。在您的情况下,您可以创建两个可序列化的类,封装单个条目数据的User
类和包含Users
对象以及数据操作方法的List<User>
类。
✔注意:根据需要命名。
◉要导入的命名空间
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
◉ User 类
[Serializable]
public class User
{
public string UserName { get; set; }
public string Password { get; set; }
//More details...
public User(string userName,string password)
{
UserName = userName;
Password = password;
}
public override string ToString() => $"{UserName},{Password}";
}
◉ 用户类
[Serializable]
public class Users
{
public readonly List<User> Accounts;
public Users() => Accounts = new List<User>();
public void Save(string filePath)
{
if (string.IsNullOrEmpty(filePath)) return;
var bf = new BinaryFormatter();
using (var fs = new FileStream(filePath,FileMode.Create))
bf.Serialize(fs,this);
}
public static Users Load(string filePath)
{
if (!File.Exists(filePath)) return null;
var bf = new BinaryFormatter();
using (var sr = new FileStream(filePath,FileMode.Open))
return bf.Deserialize(sr) as Users;
}
public bool ContainsUserName(string userName) =>
Accounts.Any(x => x.UserName == userName);
public bool ContainsAccount(string userName,string pass) =>
Accounts.Any(x => x.UserName == userName && x.Password == pass);
public User Get(string userName,string pass) =>
Accounts.FirstOrDefault(x => x.UserName == userName && x.Password == pass);
public bool Add(string userName,string pass)
{
if (ContainsUserName(userName)) return false;
Accounts.Add(new User(userName,pass));
return true;
}
}
在实现中,要创建,加载和保存数据:
//Load...
users = Users.Load(dataFilePath);
//Or create new object...
if (users is null)
users = new Users();
//and when it comes to save...
users.Save(dataFilePath);
使用ContainsUserName
方法来查找给定的用户名是否已经存在,因此可以避免重复。 Add
方法将执行相同的操作,并将有效的新条目添加到列表中。 Get
方法在列表中搜索给定的用户名和密码,并返回User
对象(如果有)null
,如果您不这样做,ContainsAccount
方法将执行相同的操作无需返回User
对象。
var user = users.Get("user","pass");
if (user is null)
Console.WriteLine("Incorrect username and/or password...");
//or
if (!users.ContainsAccount("user","pass"))
Console.WriteLine("Incorrect username and/or password...");
将其应用于您的main
:
public static void Main(string[] args)
{
Console.WriteLine("To Login Type 1,To Create a new account Type 2");
int LogInOrSignUp;
do
{
int.TryParse(Console.ReadLine(),out LogInOrSignUp);
} while (LogInOrSignUp != 1 && LogInOrSignUp != 2);
var filePath = Path.Combine(AppContext.BaseDirectory,"SignUp.dat");
var userName = "";
var password = "";
var successfull = false;
var userDetails = Users.Load(filePath);
if (userDetails is null)
userDetails = new Users();
while (!successfull)
{
if (LogInOrSignUp == 1)
{
Console.WriteLine("Write your username:");
userName = Console.ReadLine();
Console.WriteLine("Enter your password:");
password = Console.ReadLine();
if (userDetails.ContainsAccount(userName,password))
{
Console.WriteLine("You have logged in successfully!");
successfull = true;
break;
}
else
Console.WriteLine("Your username or password is incorect,try again!");
}
else //if (LogInOrSignUp == 2)
{
Console.WriteLine("Enter a username:");
userName = Console.ReadLine();
if (userDetails.ContainsUserName(userName))
Console.WriteLine("The username is taken. Try another one.");
else
{
Console.WriteLine("Enter a password:");
password = Console.ReadLine();
successfull = true;
userDetails.Add(userName,password);
userDetails.Save(filePath);
Console.WriteLine($"A new account for {userName} has been created.");
}
}
}
Console.ReadLine();
}
✔注意:最好使用switch语句而不是LogInOrSignUp
语句来选择if
,
由于OP在一个文件中提供了有关多个凭证的详细信息。
最常见的方式是序列化。二进制或xml都可以。
相关主题:
Saving Data Structures in C#
但是与版本兼容可能是您的下一个问题。
Version tolerant serialization可能会解决您的问题。
======
假设您的文件夹中有一堆txt。
必须完成两件事。
- 一个函数接受文件路径参数。
- 帮助您遍历所有文件的功能。
重写DeserializeSignUpDetails
以获取文件路径。
public static Users DeserializeSignUpDetails( string szPath)
{
Stream stream = new FileStream( szPath,FileMode.Open,FileAccess.Read);
IFormatter formatter = new BinaryFormatter();
Users objnew = (Users)formatter.Deserialize(stream);
stream.Close();
return objnew;
}
浏览文件并获取所有登录凭据。可以将其放在您的主程序中。
List<Users> GetAllLoginCredential()
{
List<Users> list = new List<Users>();
string[] files = Paths.GetFileName( "D:\\YourDirectory" );
foreach( var path in files ){
Users user = SaveToFile.DeserializeSignUpDetails( path );
list.Add( user );
}
}
然后,您可以检查每个用户。另外,您可能希望对其进行缓存,以防止重复打开文件。
顺便说一下,Users
只有一个用户信息,您可能希望它是User
。
,
您可能需要查看的耦合点-
- 将类名从
Users
更改为User
,因为这是user
的单一表示形式。
-
您可以将文件中存储的所有用户convert
List<User>
如下所示:
public static List<Users> DeserializeSignUpDetails()
{
List<Users> users = new List<Users>();
using (Stream stream = new FileStream(@"SignUp.txt",FileAccess.Read))
{
if (stream.Length != 0)
{
BinaryFormatter formatter = new BinaryFormatter();
while (stream.Position != stream.Length)
{
users.Add((Users)formatter.Deserialize(stream));
}
return users;
}
}
return users;
}
-
然后您可以在Main类中使用它,如下所示:
List<Users> userDetails = SaveToFile.DeserializeSignUpDetails();
如下所示的登录验证期间
AND :
if (userDetails != null)
{
foreach (Users user in userDetails)
{
if (userName == user.UserName && password == user.Password)
{
Console.WriteLine("You have logged in successfully!");
successfull = true;
break;
}
if (!successfull)
{
Console.WriteLine("Your username or password is incorect,try again!");
}
}
}
其他通知:
-
在读取流以正确处置时使用using
。
-
在序列化/反序列化之前检查Null
或empty
的流,以鼓励defensive programming
--p
if (stream.Length != 0)
本文链接:https://www.f2er.com/2208081.html