C# C创建类列表/Dictionary,将.txt文件作为数据库写入和读取,而不覆盖数据

C# C创建类列表/Dictionary,将.txt文件作为数据库写入和读取,而不覆盖数据,c#,list,file,keychain,C#,List,File,Keychain,这是你们在这里遇到的最常见的问题之一,所以请原谅我,但无论我怎么努力,我都无法克服这个问题 我正在为Windows窗体应用程序中的一个项目构建一个密钥链应用程序,为了尽可能容易地理解这个概念,我使用了列表而不是字典//iList 这是我一直在使用的类: public class Account { public static List<Account> myAccountList = new List<Account>(); public string D

这是你们在这里遇到的最常见的问题之一,所以请原谅我,但无论我怎么努力,我都无法克服这个问题

我正在为Windows窗体应用程序中的一个项目构建一个密钥链应用程序,为了尽可能容易地理解这个概念,我使用了列表而不是字典//iList

这是我一直在使用的类:

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);
    }
}

根据你的评论,这听起来像是你想追加而不是写。如果您想附加到一个文件,即添加到已经存在的内容,您需要使用AppendAllLines函数

但是,您有更大的问题,因为您正在尝试向文件中写入对象列表,而不是字符串。如果您只想写入密码,则需要:

private static void SaveToFile()
{
    System.IO.File.AppendAllLines("path/to/file", myAccountList.Select(x => x.Password));
}
如果文件存在,此方法将附加到该文件,如果文件不存在,则只创建一个新文件

文档

WriteAllines需要字符串[]作为第二个参数。因此,您需要创建一种将单个Account对象表示为字符串的方法。最简单的方法是重写ToString方法。然后使用Linq Select方法来选择它们

此外,如果Account类不包含帐户列表,则会更好。那真的应该是一个单独的类。试着这样做:

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}";
    }
}

好的,那么你的问题是什么?@maccettura我想知道我将列表写入文件的方式有什么问题,以及如何防止save方法覆盖.txt中以前的凭据file@S.Nog我更新了我的答案,我没有注意到您试图将IEnumerable写入文件。我假设您的代码已编译。它似乎创建了.txt文件,但实际上并没有将密码字符串写入该文件。是的,它从一开始就没有编译。我应该澄清一下。你确定myAccountList有密码不是空的项目吗?调试程序的步骤是否可能是我错误地介绍了列表?如果我将它从一个列表切换到一个数组,它将非常有效,但这里的目标是让我自己熟悉列表。我现在正在通过调试器,这对于我目前的理解来说是非常先进的,但是我毫不怀疑它会帮助其他人,所以我会将它标记为正确的。谢谢
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}";
    }
}