【问题标题】:Write dictionary to file, retrieve dictionary from file将字典写入文件,从文件中检索字典
【发布时间】:2021-10-22 19:05:00
【问题描述】:

我正在用 C# 编写一个简单的程序来添加、删除、更改和查看键值对。我想将此代码中使用的字典保存在文件中。我想在启动程序时从文件中加载这个字典,并在退出时保存编辑的字典。

我已经编写了从文本文件写入字典的代码,以及在退出时将字典写入文本文件的代码。每当我使用空文本文件运行程序时,它都会正常执行并将任何新条目添加到字典中。退出并将这些新的字典键值保存到文本文件后,当我再次尝试加载程序时,似乎密钥对已经在字典中并且不会运行程序。

我的字典里面也没有任何内容。

将新字典保存到文本文件的代码是

private void btnExit_Click(object sender, EventArgs e)
{
    File.WriteAllLines("myfile.txt",
    names.Select(x => "[" + x.Key + "," + x.Value + "]").ToArray());
    this.Close();
}

这将使文本文件中的输出以这种格式输出

[jackP@gmail.com, 杰克]
[ashleyD@gmail.com,阿什利]
[samF@gmail.com, 山姆]

将更新后的文本文件输出到字典的代码是

private void Form1_Load(object sender, EventArgs e)
{
    StreamReader sr = new StreamReader("myfile.txt");
    string line;

    while ((line = sr.ReadLine()) != null)
    {
        string[] arr = line.Split(',');
        int i = 0;
        while (i < arr.Length)
        {
            names.Add(arr[i], arr[i + 1]);
            i += 2;
        }
    }
}

【问题讨论】:

  • 我在哪里遗漏了问题?
  • 您的问题、问题或错误是什么?
  • @Milad 标签必须告诉您问题是什么关于,而不是问题的内容。 winforms 标签不合适,因为问题与 winforms 无关,所以我删除了该标签。
  • 您确定names.Select(x =&gt; "[" + x.Key + "," + x.Value + "]") 创建的是纯CSV 文件吗?看起来它会创建一个 csv 文件,每一行都用括号括起来
  • 另外,文件中的每一行似乎只有一个名称。你可以只做names[arr[0]] = arr[1] 而不是在那里有一个while循环。

标签: c# file dictionary


【解决方案1】:

代替

names.Add(arr[i], arr[i + 1]);

你可以

names[arr[i]] = arr[i + 1];

第二种方法只是用新值覆盖字典中的任何现有条目,而不是在 Key 存在时崩溃。您还可以选择使用不会崩溃的 TryAdd,如果密钥存在则不会添加。您可以使用 bool 返回值来确定是否添加了键/值,如果没有,您可以调用一些更复杂的逻辑,例如将现有项目与您要添加的项目合并

关于您的问题,我无法解决的一件事是,您的写入代码用方括号括住了值,但读取代码对它们没有任何作用,并且您发布的示例文件不包含它们。 .

除此之外,还有一个 File.ReadAllLines,它类似于 File.WriteAllLines,但方向相反;从文件中生成一个数组。如果您不喜欢 CSV,那么序列化为 json 可能会简单得多 - 最流行的 json 序列化程序有帮助页面,显示如何在字典和 json 字符串之间进行转换,您可以一次将其写入文件(File.WriteAllText) - 此处的帮助页面:https://www.newtonsoft.com/json/help/html/serializedictionary.htm - 我会链接到一个 SO 问题,但规范的问题往往在主题上有很多变化(包括 JavaScriptSerializer 等古老的东西) - 它基本上相当于一行代码, 加上另一个写作:

var str = JsonConvert.SerializeObject(yourDictionary);
File.WriteAllText(path, str);

读回来会是这样的:

var dict = JsonConvert.DeserializeObject<Dictionary<string,string>>(File.ReadAllText(path));

这是一个非常好的轮子,它已经被发明出来并解决了您可能最终面临的许多问题,例如包含逗号的键或值等

【讨论】:

  • 您的回复非常有帮助,我为没有意识到我可以使用新值设置该位置的新键而感到愚蠢。我在输入问题时忘记删除写作中的括号。
  • 哈,没必要傻了;我仍然需要在谷歌上搜索诸如“WriteAllText 中首先是路径还是字符串”之类的东西,而我只使用了大约 20 年......要记住的东西太多了......:D
【解决方案2】:

如果密钥中有逗号,这仍然会给您带来问题,但比原来的要少得多:

private void btnExit_Click(object sender, EventArgs e)
{
    File.WriteAllLines("myfile.txt",
        names.Select(x => $"{x.Key},{x.Value}"));
    this.Close();
}

private void Form1_Load(object sender, EventArgs e)
{
    var lines = File.ReadLines("myfile.txt");
    foreach(var line in lines)
    {
        string[] arr = line.Split(',');
        names.Add(arr[0], String.Join(",", arr.Skip(1)));
    }
}

最好包含一个真正的 CSV 编写器/解析器并使用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-10
    • 2016-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    相关资源
    最近更新 更多