[英]comparing the contents of two huge text files quickly
我基本上想做的是比较两个巨大的文本文件,如果匹配,则写出一个字符串,我已经写过了,但是速度非常慢。 我希望你们可能有一个更好的主意。 在下面的示例中,我正在比较collect [3] splitfound [0]
string[] collectionlist = File.ReadAllLines(@"C:\found.txt");
string[] foundlist = File.ReadAllLines(@"C:\collection_export.txt");
foreach (string found in foundlist)
{
string[] spltifound = found.Split('|');
string matchfound = spltifound[0].Replace(".txt", ""); ;
foreach (string collect in collectionlist)
{
string[] splitcollect = collect.Split('\\');
string matchcollect = splitcollect[3].Replace(".txt", "");
if (matchcollect == matchfound)
{
end++;
long finaldest = (start - end);
Console.WriteLine(finaldest);
File.AppendAllText(@"C:\copy.txt", "copy \"" + collect + "\" \"C:\\OUT\\" + spltifound[1] + "\\" + spltifound[0] + ".txt\"\n");
break;
}
}
}
抱歉,模糊的人,
我想做的只是简单地说,如果一个文件中的内容存在于另一个文件中,则写出一个字符串(该字符串并不重要,只是找到两个比较对象的时间是)。 收藏列表是这样的:
苹果|农场
Foundlist是这样的
C:\\牛\\马\\ turtle.txt
C:\\牛\\猪\\ apple.txt
我正在做的是从collectionlist中获取apple,并在foundlist中找到包含apple的行。 然后写出一个基本的Windows复制批处理文件。 对困惑感到抱歉。
答案(全部归功于Slaks)
string[] foundlist = File.ReadAllLines(@"C:\found.txt");
var collection = File.ReadLines(@"C:\collection_export.txt")
.ToDictionary(s => s.Split('|')[0].Replace(".txt",""));
using (var writer = new StreamWriter(@"C:\Copy.txt"))
{
foreach (string found in foundlist)
{
string[] splitFound = found.Split('\\');
string matchFound = Path.GetFileNameWithoutExtension(found);
string collectedLine;
if (collection.TryGetValue(matchFound,out collectedLine))
{
string[] collectlinesplit = collectedLine.Split('|');
end++;
long finaldest = (start - end);
Console.WriteLine(finaldest);
writer.WriteLine("copy \"" + found + "\" \"C:\\O\\" + collectlinesplit[1] + "\\" + collectlinesplit[0] + ".txt\"");
}
}
}
调用File.ReadLines() (.NET 4),而不是ReadAllLines() (.NET 2.0)。
ReadAllLines
需要构建一个数组来保存返回值,这对于大型文件而言可能非常慢。
如果您不使用.Net 4.0,则将其替换为StreamReader。
使用matchCollect
(一次)构建一个Dictionary<string, string>
,然后遍历foundList
并检查HashSet是否包含matchFound
。
这使您可以用O(1)哈希检查替换O(n)内部循环
使用StreamWriter而不是调用AppendText
编辑 :调用Path.GetFileNameWithoutExtension
和其他Path
方法,而不是手动操作字符串。
例如:
var collection = File.ReadLines(@"C:\found.txt")
.ToDictionary(s => s.Split('\\')[3].Replace(".txt", ""));
using (var writer = new StreamWriter(@"C:\Copy.txt")) {
foreach (string found in foundlist) {
string splitFound = found.Split('|');
string matchFound = Path.GetFileNameWithoutExtension(found)
string collectedLine;
if (collection.TryGetValue(matchFound, collectedLine)) {
end++;
long finaldest = (start - end);
Console.WriteLine(finaldest);
writer.WriteLine("copy \"" + collectedLine + "\" \"C:\\OUT\\"
+ splitFound[1] + "\\" + spltifound[0] + ".txt\"");
}
}
}
首先,我建议对两个文件进行规范化,然后将其中一个放入一组。 这使您可以快速测试是否存在特定的行,并将复杂度从O(n * n)降低到O(n)。
另外,您不应该在每次写一行时打开和关闭文件:
File.AppendAllText(...); // This causes the file to be opened and closed.
在操作开始时,一次打开输出文件,向其中写入行,然后在写完所有行后将其关闭。
您具有笛卡尔积,因此有意义的是一侧索引而不是进行详尽的线性搜索。
从一个文件中提取密钥,并使用Set或SortedList数据结构来保存它们。 这将使查找快得多。 (您的总体算法将是O(N lg N)而不是O(N ** 2))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.