要阅读我试过这段代码:
在Form1的顶部,我做了:
Dictionary<string, List<string>> LocalyKeyWords = new Dictionary<string, List<string>>();
在构造函数中我做了:
keywords = @"d:\Keywords.txt";
if (File.Exists(keywords))
{
LoadKeys(LocalyKeyWords, keywords);
}
功能LoadKeys:
private void LoadKeys(Dictionary<string,List<string>> disctionary, string FileName)
{
var lines = File.ReadAllLines(keywords).Select(l => l.Split(','));
var dict = new Dictionary<string, List<string>>();
foreach(var splits in lines)
{
var key = splits.First();
var value = splits.Skip(1).ToList();
try {dict.Add(key, value);
}
catch(Exception ex)
{ } }
}
没有例外,但在调用函数后的构造函数中完成所有操作后,LocalyKeyWords为空。
这就是我今天写文件的关键和值:
private void button6_Click(object sender, EventArgs e)
{
using (var w = new StreamWriter(keywords))
{
crawlLocaly1 = new CrawlLocaly();
crawlLocaly1.StartPosition = FormStartPosition.CenterParent;
DialogResult dr = crawlLocaly1.ShowDialog(this);
if (dr == DialogResult.OK)
{
if (LocalyKeyWords.ContainsKey(mainUrl))
{
LocalyKeyWords[mainUrl].Clear();
LocalyKeyWords[mainUrl].Add(crawlLocaly1.getText());
}
else
{
LocalyKeyWords[mainUrl] = new List<string>();
LocalyKeyWords[mainUrl].Add(crawlLocaly1.getText());
}
foreach (KeyValuePair<string, List<string>> kvp in LocalyKeyWords)
{
w.WriteLine(kvp.Key + "," + string.Join(",", kvp.Value));
}
}
}
}
也许现在你将能够解决在构造函数中加载键和值的问题,并解决每次在button6点击事件中更改键或值时如何编写的问题。
答案 0 :(得分:3)
var lines = File.ReadAllLines("path/to/file").Select(l => l.Split(','));
var dict = new Dictionary<string, List<string>();
foreach(var splits in lines)
{
var key = splits.First();
var value = splits.Skip(1).ToList();
try {dict.Add(key, value);}
catch(Exception ex) { //TODO: handle }
}
return dict;
答案 1 :(得分:2)
如果你有一个非常大的文件,强烈建议使用ReadLines而不是ReadAllLines
,ReadLines
是延迟执行,并且不会将所有行加载到内存中,ReadAllLines
是将所有行加载到内存时没有太多优化:
var result = File.ReadLines("text.txt")
.Select(line => line.Split(','))
.ToDictionary(x => x.First(),
x => x.Skip(1).ToList());
如果你有相同的密钥,Dictionary
不是一个好选择,你可以使用:
var result = File.ReadLines("text.txt")
.Select(line => line.Split(','))
.Select(x => new KeyValuePair<string, List<string>>(x.First(), x.Skip(1).ToList()));
答案 2 :(得分:2)
基于上述建议,这会将任何重复的键组合在一起,并为每个键提供唯一的值。
// Turn the file into an Enumerable of lines
var dict = File.ReadLines("path/to/file")
// For each line, turn it into an array of comma-separated values
.Select(line => line.Split(','))
// Group the lines together by their first token (the key)
// The values of the groupings will be the "tokenized" lines
.GroupBy(line => line[0])
// Create a dictionary from the collection of lines,
// using the Key from the grouping (the first token)
.ToDictionary(group => group.Key,
// Set the values of each entry to the arrays
// of tokens found for each key (merging
// them together if a key was found multiple times)
group => group.SelectMany(values =>
// ...ignoring the first token and filtering
// out duplicate values
values.Skip(1).Distinct().ToList()));
return dict;
例如,包含以下文本的文件:
1,a,b,c
1,c,d,e
2,e,f,g
将转换为以下字典:
1 : {a,b,c,d,e}
2 : {e,f,g}
正如@Vlad所指出的,您不需要过滤掉任何重复项,因为该文件应该从Dictionary生成,并且不应包含重复项。 我强烈建议找出文件重复的原因,然后解决问题。然后,您可以大大简化将文件加载到字典中的功能,删除分组和Distinct
调用留下以下内容:
var dict = File.ReadLines("path/to/file")
// For each line, turn it into an array of comma-separated values
.Select(line => line.Split(','))
// Create a dictionary from the collection of lines,
// using the the first token as the key
.ToDictionary(tokens => tokens[0],
// Set the value of each entry to the a
// list containing each token on that line
// (after the first, which is the key)
tokens => tokens.Skip(1).ToList());
return dict;
答案 3 :(得分:1)
嗯,基本上你的阅读与写作相反。
您打开文件(var w = new StreamReader(keywords)
),逐行阅读(while (w.Peek() >= 0) { var l = sr.ReadLine()); ...
(甚至更好string l; while ((l = sr.ReadLine()) != null) { ...
),并解析每一行。
对于解析一行,您可以使用string.Split
将其拆分为逗号,因此您的键是部件列表中的第0个条目,其余部分是值。
编辑:在没有Peek
的情况下添加了替代解决方案,感谢@Jon。
答案 4 :(得分:1)
string line = System.String.Empty;
using (StreamReader sr = new StreamReader("MyFile.txt")
{
while ((line = sr.ReadLine()) != null)
{
string[] tokens = line.Split(',');
LocalKeyWords.Add(tokesn[0], tokens[1]);
}
}
你也应该将它包装在try catch中。
答案 5 :(得分:1)
<强>代码:强>
var delimiter = new[] {','};
var splits = File.ReadLines("text.txt")
.Where(line => !string.IsNullOrWhiteSpace(line))
.Select(line => line.Split(delimiter));
// Add "StringSplitOptions.RemoveEmptyEntries" if you want
// Add ".Where(split => split.Length > 1)" to exclude empty keys
var lookup = splits.ToLookup(split => split[0], split => split.Skip(1));
var dict = lookup.ToDictionary(x => x.Key, x => x.SelectMany(s => s).ToList());
调试更少,但线路更少:
var dict = File.ReadLines("text.txt")
.Where(line => !string.IsNullOrWhiteSpace(line))
.Select(line => line.Split(delimiter))
.ToLookup(split => split[0], split => split.Skip(1))
.ToDictionary(x => x.Key, x => x.SelectMany(s => s).ToList());
示例输入:
1,a,b,c
2,a,b,c
1,a,e,d
3
2,一个
4,a,b
<强>输出:强>
1:{a,b,c,a,e,d}
2:{a,b,c,a}
3:{}
4:{a,b}