如何有效地索引文件?

How can I efficiently index a file?

我正在处理一个需要从一系列可能很大的文本文件 (~3+ GB) 中随机读取整行文本的应用程序。

线条的长度可以不同。

为了减少 GC 并创建不必要的字符串,我正在使用提供的解决方案: 来检测每个新行并将其一次性存储在地图中,从而生成索引lineNo => position 即:

// maps each line to it's corresponding fileStream.position in the file    
List<int> _lineNumberToFileStreamPositionMapping = new List<int>();
  1. 浏览整个文件
  2. 当检测到 new line 增量时 lineCount 并将 fileStream.Position 添加到 _lineNumberToFileStreamPositionMapping

然后我们使用 API 类似于:

public void ReadLine(int lineNumber)
{
     var getStreamPosition = _lineNumberToFileStreamPositionMapping[lineNumber];
     //... set the stream position, read the byte array, convert to string etc.
}

该解决方案目前提供了良好的性能,但有两点我不喜欢:

  1. 因为我不知道文件中的总行数,所以我无法预分配一个 array 因此我必须使用一个 List<int> ,它可能会降低效率,将大小调整为原来的两倍我真的需要;
  2. 内存使用量,以约 1GB 的文本文件为例,其中包含约 500 万行文本,索引占用约 150MB,我真的很想尽可能减少它。

非常感谢任何想法。

  1. 使用List.Capacity手动增加容量,大概每1000行左右。

  2. 如果你想用性能换取内存,你可以这样做:不是存储每一行​​的位置,而是只存储每 100(或更多)行的位置。然后,当需要第 253 行时,转到第 200 行的位置并向前数 53 行。