gpt4 book ai didi

c# - 以非升序从大文件中读取多行

转载 作者:行者123 更新时间:2023-11-30 19:35:20 28 4
gpt4 key购买 nike

我有一个非常大的文本文件,超过 1GB,我有一个表示行号的整数列表,需要生成另一个文件,其中包含新文件中原始文件行号的文本。

原始大文件示例:

ogfile line 1
some text here
another line
blah blah

所以当我得到“2,4,4,1”列表时,输出文件应该是:

some text here
blah blah
blah blah
ogfile line 1

我试过了 string lineString = File.ReadLines(filename).Skip(lineNumList[i]-1).Take(1).First();

但这需要很长时间,因为必须读入文件,跳到有问题的行,然后下次重新读取...我们正在谈论 1GB 文件和我的 List<int> 中的数百万行。是几千个行号。

有没有更好/更快的方法来阅读单行,或者让读者跳到特定行号而不是逐行“跳过”?

最佳答案

此处的高阶位是:您正在尝试使用文本文件解决数据库问题。数据库旨在解决大数据问题;正如您所发现的,文本文件在随机访问时非常糟糕。 使用数据库,而不是文本文件

如果您一心想使用文本文件,那么您要做的就是利用您对可能出现问题的参数的了解。例如,如果您知道,正如您所暗示的那样,有 ~1M 行,每行约 1KB,要提取的行集占总行的 ~0.1%,那么您可以想出一个有效的解决方案,例如这个:

  • 制作一个包含要阅读的行号的集合。该集合必须快速检查成员资格。
  • 制作一个字典,将行号映射到行内容。这必须能够快速地按键查找,并且能够快速地添加新的键/值对。
  • 一次读取文件的每一行;如果行号在集合中,则将内容添加到字典中。
  • 现在迭代行号列表并映射字典内容;现在我们有一个字符串序列。
  • 将该序列转储到目标文件。

我们有五个操作,所以希望大约是五行代码。

void DoIt(string pathIn, IEnumerable<int> lineNumbers, string pathOut)
{
var lines = new HashSet<int>(lineNumbers);
var dict = File.ReadLines(pathIn)
.Select((lineText, index) => new KeyValuePair<int, string>(index, lineText))
.Where(p => lines.Contains(p.Key))
.ToDictionary(p => p.Key, p => p.Value);
File.WriteAllLines(pathOut, lineNumbers.Select(i => dict[i]));
}

好的,六点就搞定了。还不错。


请注意,我使用了所有这些假设; 如果违反了假设,那么这就不再是一个好的解决方案。特别地,我们假设字典与输入文件的大小相比会很小。如果情况并非如此,那么您将需要更复杂的技术来提高效率。

相反,我们可以提取额外的效率吗? 是的,前提是我们知道有关可能输入的事实。例如,假设我们知道同一个文件将被迭代多次但具有不同的行号集,但这些集很可能有重叠。在那种情况下,我们可以重新使用字典,而不是重建它们。也就是说,假设之前的操作留下了 Dictionary<int, string>为第 (10, 20, 30, 40) 行和文件 X 计算。如果随后请求针对文件 X 的第 (30, 20, 10) 行,我们已经在内存中有了字典。

我想在这个答案中表达的关键是,您必须知道一些关于输入的信息才能构建有效的解决方案;您对输入的限制越多,您构建的解决方案就越有效。充分利用您对问题领域的所有了解。

关于c# - 以非升序从大文件中读取多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58309090/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com