查找大型(20gb)文本文件中对象的属性



我有一个大的20 GB的文本文件,条目类似于entry1MainText:entry1Name,行分隔。

我需要看看一个对象的属性是否在这些行中匹配entry1MainText。到目前为止,我有下面的代码(在c#中读取带有流的大文本文件),读取文件的一行并执行foreach对象属性。我意识到这可能不是最有效的方法。

string file = @"C:test.txt";
using (FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (BufferedStream bs = new BufferedStream(fs))
using (StreamReader sr = new StreamReader(bs))
{
string line;
while ((line = sr.ReadLine()) != null)
{
foreach (UsrFile usrF in rawUsrSorted)
{
if (line.Contains(usrF.Prop1))
{
gridMain.Rows.Add(usrF.Prop1, usrF.Prop2);
}
}
}
}

我确实有足够的RAM来读取文件到内存中并在那里解析,如果这将是有益的,也就是说,我已经研究了一点MemoryMappedFile,想知道这是否可能在这里使用。

  1. 实例化一个新的FileStream来访问缓冲区和标志
  2. 调整缓冲区大小,对于SSD这可能相当大,我选择了1024 * 1000(看看你的驱动器是什么)
  3. 设置FileOptions.SequentialScan标志

表示从开始顺序访问结束。系统可以将此作为优化文件缓存的提示。如果应用程序移动文件指针进行随机访问,最优缓存可能不会发生;但是,仍然可以保证正确的操作。在某些情况下,指定此标志可以提高性能。

  1. 分行
  2. 使用Dictionary

示例

var dict = rawUsrSorted
.ToDictionary(x => x.Prop1, x => x.Prop2);
using var fs = new FileStream(
file, 
FileMode.Open, 
FileAccess.Read, 
FileShare.ReadWrite, 
1024 * 1000, 
FileOptions.SequentialScan);
using var sr = new StreamReader(fs);
string line;
while ((line = sr.ReadLine()) != null)
{
var prop = line[..line.IndexOf(":")];
if (dict.TryGetValue(prop, out var prop2))
gridMain.Rows.Add(prop, prop2); 
}

<子>注意:这是完全未经测试的,可能包含任何数量的拼写错误,语法错误或错误,缺乏适当的错误检查和容错

<子>还要注意

您应该真正使用数据库,与索引表相比,扫描20g文件的效率非常低。

最新更新