1

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

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

例如,像这样的列表;

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

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

4

4 回答 4

4

File.WriteAllText写入一个新文件。每次遍历 for 循环时,您都在覆盖文件,只给您最后一行。

msdn页面显示

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

你可以File.WriteAllTextFile.AppendAllTextwhich 替换:

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

如果您想一次全部写入文件,您可以使用File.WriteAllLines(string path,IEnumerable<string> 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);
于 2013-10-10T20:26:03.563 回答
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 中将所有这些行替换为一个。

于 2013-10-10T20:27:06.060 回答
2

哈里森回答了为什么你的代码不起作用......现在让我告诉你为什么琼斯(粗鲁地)建议你使用 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当你真的只需要计数时创建项目组,所以它在内存使用方面有点重——但这通常不是一个非常重要的因素。关于简洁,有话要说。

于 2013-10-10T20:35:50.127 回答
0

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

于 2013-10-10T20:27:25.383 回答