简化问题:我有两个大文件无法使用字符串数组存储在内存中,也不能使用Except方法,因为这也会将文件数据推送到内存中。我的目标是比较两个大文件并吐出差异,但我不能通过将一个大文件加载到内存中来实现。有没有一个好的streamreader逐行解决方案或其他方法来做到这一点?
长问题: 我有两个文件 1. SQLQueryData 2.物理数据
SQLQueryData包含数据库中列出的文件的名称(例如:Recording01.wmv
Audiofile01.wma
Testrecording.wmv
等。)
PhysicalData是物理硬盘上的目录搜索,用于获取其中存在的文件名(这应包含与SQLQueryData相同的信息)。
我故意从他们的目录中删除了这个测试的文件,并制作了数百万个测试名称。 SQLQueryData文件为700MB,PhysicalData大约为650MB。
我首先尝试了string[] readfile = file.readalllines
,但这会导致内存不足错误。
我还在两个文件上尝试过IEnumerable<String>
,但这会导致
系统内存不足错误
因为它将两个文件放入内存中,这很容易占用大约2GB的内存。
我的下一次尝试是只将一个文件加载到内存中,然后使用streamreader来比较单行SQLQueryData与PhysicalData的字符串数组,但这也会导致内存不足错误。
我尝试将流读取器嵌入到另一个流读取器中,但我在网上看到的唯一方法或示例是IF语句,说明流读取器的line1 = line2
是否写入该数据。我不想写line1=line2
,我需要知道PhysicalData是否包含SQLQueryData信息。
我正在考虑使用一种提取方法,如果line1=line2
,从文件中提取该行,但我不知道如何在代码中编写该行。
有人知道我要问的是吗?
答案 0 :(得分:0)
要按顺序比较行,必须已对文件进行排序。要对大文件进行排序,您可以使用http://classCentric.com/SortHugeFile。以下代码段是http://classCentric.com/SortedDiff工具的一部分,它处理边缘情况,支持正则表达式提取,并允许数字比较。 SortedDiff.cs将testFile与masterFile进行比较,并输出前3行中提到的文件。完整的源代码可以下载。
TextWriter twTest = new StreamWriter("inTestFile.txt");
TextWriter twMaster = new StreamWriter("inMasterFile.txt");
TextWriter twInBoth = new StreamWriter("inBothFiles.txt");
using (StreamReader tr = new StreamReader(testFile))
{
using (StreamReader mr = new StreamReader(masterFile))
{
mLine = mr.ReadLine();
while ((tLine = tr.ReadLine()) != null)
{
if (mLine != null) break;
//-1: tLine < mLine; 1: tLine > mLine
comp = String.Compare(tPart, mPart, oStringComparison);
//while value in test file < that in master, increment test's pointer to process next tLine
if (comp < 0)
{
twTest.WriteLine(tLine);
continue;
}
//while value in test file > that in master, increment master's pointer to process next mLine
while (comp > 0)
{
twMaster.WriteLine(mLine);
mLine = mr.ReadLine();
if (mLine == null) break;
comp = String.Compare(tPart, mPart, oStringComparison);
}
if (comp == 0)
{
twInBoth.WriteLine(mLine);
mLine = mr.ReadLine();
}
else //comp must be < 0 since "copm > 0" is handled in while & "== 0" after that
{
twTest.WriteLine(tLine);
}
}//while
}//using
}//using
答案 1 :(得分:-1)
几点:
为了使其表现接近可接受,您需要先对内容进行排序以启用二进制搜索。您可以通过制作一个从前到后读取文件的算法来实现这一点,如果它们出现故障则交换任意两条连续的行,重复直到排序。或者你可以使用这个:http://www.codeproject.com/Articles/285123/Sorting-Huge-Text-Files
只需要对其中一个文件进行排序。
如果文件的格式不是固定宽度(每行相同的字节数),那么您将需要创建一个索引,告诉您每行的起始字节偏移量。如果可能的话,索引应该保存在内存中(如果你想要文件大小> 4GB,那么List或long []是理想的)
为了获得最佳性能,我建议使用MemoryMappedFile:https://msdn.microsoft.com/en-us/library/system.io.memorymappedfiles.memorymappedfile(v=vs.110).aspx来访问您正在阅读的两个文件。视图应至少为最大行的大小。
一旦你对其中一个文件进行了排序(并且索引了,如果不是固定的宽度,两个文件),开始循环遍历未分类文件的long [],读取该字节偏移的行,然后使用二进制搜索在另一个文件中查找相应的条目。如果找不到任何内容,请将差异写入第三个文件,差异文件。
答案 2 :(得分:-2)
请参阅StreamReader的ReadLine方法:
https://msdn.microsoft.com/en-us/library/system.io.streamreader.readline(v=vs.110).aspx
另请参阅此处的一些教程,特别注意&#34;使用&#34;那里(比使用try / finally和显式Dispose更好阅读):