C# 创建一个 Class List<>/Dictionary<>,作为数据库写入和读取 .txt 文件而不覆盖数据
C# Creating a Class List<>/Dictionary<>, writing to and reading from .txt file as a database without overwriting data
这是你们在这里遇到的最常见的问题之一,所以请原谅我,但无论我如何努力搜索,我都无法解决这个问题。
我正在为 Windows Forms Application 中的项目构建一个钥匙串应用程序,为了尽可能容易地理解这个概念,我使用了 List<> 而不是 Dictionary//iList
这是我一直在使用的Class:
public class Account
{
public static List<Account> myAccountList = new List<Account>();
public string Domain; //this is supposed to be google/skype/facebook
public string Email;
public string Username;
public string Password;
public Account (string domain, string email, string username, string password)
{
Domain = domain;
Email = email;
Username = username;
Password = password;
myAccountList.Add(new Account(domain, email, username, password)); //constructor calls the new list instance
}
private static void SaveToFile()
{
System.IO.File.WriteAllLines(@accountdb.txt, myAccountList);
}
private static void ReadFromFile() // this is meant to be used as authentication in my main form, it isn't necessary right now..
{
System.IO.File.ReadAllLines(@accountdb.txt);
}
}
我有几个问题:
- 我无法创建功能性保存方法来写入文件,我在
System.IO
中尝试了几种方法
- 当我把列表改成一维数组时,它会不断覆盖,我想模拟一下MySQL,以便以后熟悉。
调用构造函数的按钮点击事件:
private void buttonSave_Click(object sender, EventArgs e)
{
string domain, email, username, password;
domain = comboboxDomain.Text;
email = textboxEmail.Text;
username = textboxUsername.Text;
password = textboxPassword.Text;
//Checking for correct EMAIL
if (!textboxEmail.Text.Contains("@") && (!textboxEmail.Text.Contains(".")))
{
MessageBox.Show("Invalid Email Format");
}
else
{
Account account = new Account(domain, email, username, password);
}
}
根据您的评论,您似乎想要 append 而不是 write。如果你想附加到一个文件(即添加到已经存在的内容),你需要使用 AppendAllLines()
函数。
但是您遇到了更大的问题,因为您正在尝试将对象列表而不是字符串写入您的文件。如果你只想写密码,你需要这个:
private static void SaveToFile()
{
System.IO.File.AppendAllLines("path/to/file", myAccountList.Select(x => x.Password));
}
如果文件存在,此方法将追加到文件,如果不存在,则创建一个新文件。
文档here
WriteAllLines
期望 string[]
作为第二个参数。因此,您需要创建一种方法来将单个 Account
对象表示为字符串。最简单的方法是覆盖 ToString
方法。然后使用 Linq Select
方法来 select 它们。
此外,如果 Account
class 不包含帐户列表会更好。那真的应该是一个单独的class。尝试这样的事情:
void Main()
{
var accountList = new AccountList();
//Save a few accounts to the file
Account a1 = new Account("Google", "GoogleEmail", "GoogleUser", "GooglePass");
accountList.Add(a1);
Account a2 = new Account("Netflix", "NetflixEmail", "NetflixUser", "NetflixPass");
accountList.Add(a2);
AccountList.SaveToFile(@"g:\test\accounts.txt", accountList);
//Load the accounts from the file
AccountList aList2 = AccountList.ReadFromFile(@"g:\test\accounts.txt");
aList2.Dump();
}
public class AccountList
{
private List<Account> accounts;
public IEnumerable<Account> Accounts { get { return accounts;} }
public AccountList()
{
this.accounts = new List<Account>();
}
public void Add(Account a)
{
accounts.Add(a);
}
public static void SaveToFile(string filename, AccountList accounts)
{
//Selects all the `Account` instances and creates a string[]
System.IO.File.WriteAllLines(filename, accounts.Accounts.Select(a => $"{a}").ToArray());
}
public static AccountList ReadFromFile(string filename) // this is meant to be used as authentication in my main form, it isn't necessary right now..
{
var result = new AccountList();
//Read each line from the file and create an Account instance.
foreach (var line in System.IO.File.ReadAllLines(filename))
{
if (!string.IsNullOrWhiteSpace(line))
{
var parts = line.Split(',');
if (parts.Length == 4)
{
Account a = new Account(parts[0], parts[1], parts[2], parts[3]);
result.Add(a);
}
}
}
return result;
}
}
public class Account
{
public string Domain; //this is supposed to be google/skype/facebook
public string Email;
public string Username;
public string Password;
public Account(string domain, string email, string username, string password)
{
Domain = domain;
Email = email;
Username = username;
Password = password;
}
public override string ToString()
{
return $"{Domain},{Email},{Username},{Password}";
}
}
这是你们在这里遇到的最常见的问题之一,所以请原谅我,但无论我如何努力搜索,我都无法解决这个问题。
我正在为 Windows Forms Application 中的项目构建一个钥匙串应用程序,为了尽可能容易地理解这个概念,我使用了 List<> 而不是 Dictionary//iList
这是我一直在使用的Class:
public class Account
{
public static List<Account> myAccountList = new List<Account>();
public string Domain; //this is supposed to be google/skype/facebook
public string Email;
public string Username;
public string Password;
public Account (string domain, string email, string username, string password)
{
Domain = domain;
Email = email;
Username = username;
Password = password;
myAccountList.Add(new Account(domain, email, username, password)); //constructor calls the new list instance
}
private static void SaveToFile()
{
System.IO.File.WriteAllLines(@accountdb.txt, myAccountList);
}
private static void ReadFromFile() // this is meant to be used as authentication in my main form, it isn't necessary right now..
{
System.IO.File.ReadAllLines(@accountdb.txt);
}
}
我有几个问题:
- 我无法创建功能性保存方法来写入文件,我在
System.IO
中尝试了几种方法
- 当我把列表改成一维数组时,它会不断覆盖,我想模拟一下MySQL,以便以后熟悉。
调用构造函数的按钮点击事件:
private void buttonSave_Click(object sender, EventArgs e)
{
string domain, email, username, password;
domain = comboboxDomain.Text;
email = textboxEmail.Text;
username = textboxUsername.Text;
password = textboxPassword.Text;
//Checking for correct EMAIL
if (!textboxEmail.Text.Contains("@") && (!textboxEmail.Text.Contains(".")))
{
MessageBox.Show("Invalid Email Format");
}
else
{
Account account = new Account(domain, email, username, password);
}
}
根据您的评论,您似乎想要 append 而不是 write。如果你想附加到一个文件(即添加到已经存在的内容),你需要使用 AppendAllLines()
函数。
但是您遇到了更大的问题,因为您正在尝试将对象列表而不是字符串写入您的文件。如果你只想写密码,你需要这个:
private static void SaveToFile()
{
System.IO.File.AppendAllLines("path/to/file", myAccountList.Select(x => x.Password));
}
如果文件存在,此方法将追加到文件,如果不存在,则创建一个新文件。
文档here
WriteAllLines
期望 string[]
作为第二个参数。因此,您需要创建一种方法来将单个 Account
对象表示为字符串。最简单的方法是覆盖 ToString
方法。然后使用 Linq Select
方法来 select 它们。
此外,如果 Account
class 不包含帐户列表会更好。那真的应该是一个单独的class。尝试这样的事情:
void Main()
{
var accountList = new AccountList();
//Save a few accounts to the file
Account a1 = new Account("Google", "GoogleEmail", "GoogleUser", "GooglePass");
accountList.Add(a1);
Account a2 = new Account("Netflix", "NetflixEmail", "NetflixUser", "NetflixPass");
accountList.Add(a2);
AccountList.SaveToFile(@"g:\test\accounts.txt", accountList);
//Load the accounts from the file
AccountList aList2 = AccountList.ReadFromFile(@"g:\test\accounts.txt");
aList2.Dump();
}
public class AccountList
{
private List<Account> accounts;
public IEnumerable<Account> Accounts { get { return accounts;} }
public AccountList()
{
this.accounts = new List<Account>();
}
public void Add(Account a)
{
accounts.Add(a);
}
public static void SaveToFile(string filename, AccountList accounts)
{
//Selects all the `Account` instances and creates a string[]
System.IO.File.WriteAllLines(filename, accounts.Accounts.Select(a => $"{a}").ToArray());
}
public static AccountList ReadFromFile(string filename) // this is meant to be used as authentication in my main form, it isn't necessary right now..
{
var result = new AccountList();
//Read each line from the file and create an Account instance.
foreach (var line in System.IO.File.ReadAllLines(filename))
{
if (!string.IsNullOrWhiteSpace(line))
{
var parts = line.Split(',');
if (parts.Length == 4)
{
Account a = new Account(parts[0], parts[1], parts[2], parts[3]);
result.Add(a);
}
}
}
return result;
}
}
public class Account
{
public string Domain; //this is supposed to be google/skype/facebook
public string Email;
public string Username;
public string Password;
public Account(string domain, string email, string username, string password)
{
Domain = domain;
Email = email;
Username = username;
Password = password;
}
public override string ToString()
{
return $"{Domain},{Email},{Username},{Password}";
}
}