【问题标题】:Saving Dictionary contents to file将字典内容保存到文件
【发布时间】:2013-10-10 20:23:37
【问题描述】:

我正在尝试用列表和计数唯一实例来做一些非常具体的事情,然后将其保存在文件的新行中。

基本上,我有一个包含一组列的列表视图,我想遍历整个列表,并保存每个唯一项目的计数。

例如,这样的列表;

111
222
111
333
333
333

最终会被写入文件:

111:2
222:1
333:3

我不需要它按任何特定顺序排列,只要我有这些值即可。

到目前为止我有这个;

string fileName = Application.StartupPath + @"\txn_" + 
    TerminalConfig.CreateSafSig() + ".saf";

Dictionary<string, int> products = new Dictionary<string, int>();
List<string> codes = new List<string>();

foreach (ListViewItem item in BasketList.Items)
{ 
    codes.Add(item.SubItems[3].Text); 
}

String[] items = codes.ToArray();
foreach (String code in items)
{
    if (products.ContainsKey(code) != true)
    { 
        products.Add(code, 1); 
    }
    else 
    { 
        products[code] += 1; 
    }
}

foreach (var entry in products)
{ 
    File.WriteAllText(fileName, string.Format("{0}:{1}",entry.Key,entry.Value)); 
}

但它保存的文件只给了我最后一行的内容。 在上面的例子中,它只会显示333:3

我很确定我写的正确,但我正在努力找出哪里出错了。

【问题讨论】:

    标签: c# list dictionary


    【解决方案1】:

    File.WriteAllText 写入一个新文件。每次迭代你的 for 循环时,你都会覆盖文件,只给你最后一行。

    msdn 页面显示

    创建一个新文件,将内容写入文件,然后关闭 文件。如果目标文件已经存在,则覆盖。

    您可以将File.WriteAllText 替换为File.AppendAllText:

    打开一个文件,将指定的字符串附加到文件中,然后 关闭文件。如果文件不存在,此方法会创建一个 文件,将指定的字符串写入文件,然后关闭文件。

    如果你想一次性写入文件,你可以使用File.WriteAllLines(string path,IEnumerable&lt;string&gt; contents);其中

    创建一个新文件,将字符串集合写入文件,然后 然后关闭文件。

    在你的情况下替换:

    foreach (var entry in products)
    { 
        File.WriteAllText(fileName, string.Format("{0}:{1}",entry.Key,entry.Value)); 
    }
    

    与

    var entries = from entry in products select string.Format("{0}:{1}",entry.Key,entry.Value);
    File.WriteAllLines(fileName,entries);
    

    【讨论】:

    • WriteAllLines 也会覆盖一个文件。这两种方法之间的唯一区别是一个采用数组。
    【解决方案2】:

    问题是每次循环迭代都会覆盖文件。

    代码修复:

    StringBuilder str = new StringBuilder();
    
    
    foreach (var entry in products)
    {
       str.AppendLine(string.Format("{0}:{1}", entry.Key, entry.Value));
    }
    File.WriteAllText(fileName, str.ToString()); }
    

    要加入 linq 的潮流,这里是制作字典的代码:

    Dictionary<string, int> products = 
        BasketList.Items.GroupBy(element => element.SubItems[3].Text)
                        .ToDictionary(k => k.Key, c => c.Count())
    

    在 linq 中是的,它将所有这些行合二为一。

    【讨论】:

    • 我的道歉,这是一个小学生的错误,我应该在一英里外看到!感谢您惊人的快速响应 :) 标记已解决,因为它完成了出色的工作!
    【解决方案3】:

    哈里森回答了为什么你的代码不起作用...现在让我告诉你为什么琼斯(粗鲁地)建议你使用 GroupBy...

    File.WriteAllLines(fileName,
                   from item in BasketList.Items
                   group item by item.SubItems[3].Text into grp
                   select string.Format("{0}:{1}", grp.Key, grp.Count()));
    

    这有效地替换了您的所有代码。 效率较低——GroupBy 在您真的只需要计数时创建项目组,因此它在内存使用方面有点重量级——但这通常不是一个非常重要的因素.言简意赅是有道理的。

    【讨论】:

    • 我在 C# 方面的经验完全是自学的,有些东西我以前从未见过。从外观上看,您的代码示例刚刚完成了我上面的混乱,只用了四行?
    • @FrankishEQG - 是的,这使用了 linq,当你习惯它时会很有趣。
    • @CoryNelson - 我认为使用 ToDictionary() 的 linq 解决方案会更清晰。那么它可能是替代品的下降。
    【解决方案4】:

    WriteAllText 函数将使用您提供的字符串覆盖文件内容。您应该改用 AppendAllText 函数

    【讨论】:

      猜你喜欢
      • 2017-07-14
      • 2016-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-05
      • 1970-01-01
      相关资源
      最近更新 更多