最快的方式获得某些行从文本文件

本文关键字:文本 文件 方式获 | 更新日期: 2023-09-27 18:12:22

我有一些具有特定结构的文本文件。在每一行的开头,我有一些单词,例如"真"或"假"。像这样:

$True 3 5 1 8
$False 12 5 a z
$False 1,5,7 
$True 123
$True 7ao
$False 198

我需要得到一个数组,列表或类似的值:

$False 12 5 a z
$False 1,5,7 
$False 198

行数是未知的,我试图找到最快的方法来读取只有行与一个特定的开始词(假)。我尝试使用string.Split方法进行解析,然后添加到列表if word == word,但问题是速度,如果我有5-6000行,这变得很慢。像这样的事情有更快的方法吗?

最快的方式获得某些行从文本文件

这应该够快了:

var filteredLines = 
        File.ReadLines("path")
            .Where(line => line.StartsWith(word))
            .ToList()

因为ReadLines逐行迭代文件,而不是将整个文件加载到内存中(从MSDN):

ReadLines和ReadAllLines方法的区别如下:当使用ReadLines方法时,可以在返回整个集合之前开始枚举字符串集合;当您使用ReadAllLines时,您必须等待整个字符串数组返回,然后才能访问该数组。因此,当您处理非常大的文件时,ReadLines可以更有效。

试试这个:

List<string> list = new List<string>();
using (StreamReader sr = new StreamReader(yourFilePath))
{
  string line;
  while ((line = sr.ReadLine()) != null)
  {
    if (line.StartsWith("$False"))
       list.Add(line);
  }
}
// do something with your result list

如果您使用的是ReadAllLines(),这可能会导致性能问题,因为整个文件在内部以字符串数组的形式返回,拆分将是一个昂贵的操作。上面的解决方案缓解了这种情况。

我假设您尝试使用StreamReader的ReadLine方法读取行。

因此,我建议不要使用ReadLine方法,而是从头到尾逐个字节地读取,这样您就可以知道该行是否以您要查找的关键字开头。

为了达到这个目的,我总是使用FileStream,像下面这样查找行结束字符。所以你可以在sb.Insert(0, value);行

fs.Seek(0, SeekOrigin.Begin);
for (long offset = 0; offset < fs.Length; offset++)
{
    char value = (char)((byte)fs.ReadByte());
    if (value == 0xA)//  hex 'n
    {
         if (offset == fs.Length)
             continue;
    }
    else if (value == 0xD)// hex 'r
    {
         if (offset == fs.Length - 1)
             continue;
    }
    sb.Insert(0, value);
}

这应该能奏效:

var neededLines = System.IO.File.ReadAllLines(@"C:'Path'To'file.txt")
                                .Where(x => x.StartsWith("False"));
  1. 读取文件
  2. 中的所有行
  3. 取以"False"开头的

反对那些关于表演的荒谬评论:

我测试了一个类似于OPs的文件,有25200行,这在11ms中完成。这个时间甚至包括对结果(12600)的Count()调用。否则为3ms。我不认为性能是一个问题!