将大型 .text 文件与值数组进行比较

Compare large .txt file against array of values

美好的一天,我正在尝试将一个相当大的文本文件(大约 10 万行)与一个包含 1000 到 14000 个值的数组进行比较。这样做的目的是用户有一个值的文本文件,每行 1 个,并且该数组包含可能与每行匹配或不匹配的信息片段。文本文件中的每一行都是唯一的,数组中的每一项都是唯一的。

例如文本文件结构:]1

数组 (outfitCell) 将包含每行的第一个单词,但可能包含文本文件中的全部或 none 部分匹配项,例如,它将包含单词 "Is" 但不会包含该行的其余部分。我需要它来保留整行并将其写入新路径中的新文件。

我曾尝试使用文件流和标准流 reader 和编写器,但是需要大约 50 秒来进行比较并写出 "start with" 数组中的项目的行到一个新的 txt 文件中。

有没有人对我如何使它更快有任何建议,我在网上看过但似乎找不到任何有用的东西。

public static void CopyActiveFiles(List<string> files, string targetLocation, OutfitCell[] activeCells)
        {
            string tempFile = Path.Combine(Path.GetTempPath(), "tempPermit.txt");
            try
            {
                foreach (string file in files)
                {

                    File.SetAttributes(file, FileAttributes.Normal);
                    using (FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        using (BufferedStream bs = new BufferedStream(fs))
                        {
                            using (StreamReader sr = new StreamReader(bs))
                            {
                                using (var writer = File.CreateText(tempFile))
                                {
                                    string line;
                                    while ((line = sr.ReadLine()) != null)
                                    {
                                            foreach (var activeCell in activeCells)
                                            {
                                                if (line.StartsWith(activeCell.Name))
                                                {

                                                    writer.WriteLine(line);
                                                }
                                            }

                                    }
                                }
                            }
                        }
                    }

                    File.SetAttributes(tempFile, FileAttributes.Normal);
                    File.Copy(tempFile, Path.Combine(targetLocation, Path.GetFileName(file)));

我会把事情分解成 2-3 个函数。调用函数、文件函数、线程​​工作函数。

    public static void CopyActiveFiles(List<string> files, string targetLocation, OutfitCell[] activeCells)
    {
        foreach (string file in files)
        {
            CheckFile(file, activeCells);
        }
    }

    private static void CheckFile(string file, OutfitCell[] activeCells)
    {
        // Thread call
        // declare some thread safe collection.
        // var lines = File.ReadLines(file).Skip(<index>).Take(<count>);
        // Use a variant of the above line to grab a section of lines from the file to then ship out to threads.
    }

https://www.nimaara.com/counting-lines-of-a-text-file/

link 将帮助您计算文件中的行数。这对于将文件分成块很有用。数学将是必需的。可能循环 x 次,要计算 y 个项目,最后一个块的大小为 z。

我从 c​​mudict 单词文件创建了一个大文件(133k 行),只使用超过两个字符的单词,并在每行末尾添加 70 个随机 ASCII 字符。我还将单词存储在另一个文件中,并将其中的 1000 到 14,000 个提取到名为 values.

List<string>

使用 ToLookup,我按前两个字符对 values 进行分组,然后将行与适当的子组进行比较。我还删除了 BufferedStream,因为各种博客表明它不会提高阅读性能,在这种情况下会减慢速度。

运行 你根据我的数据编写的代码用了大约 14.7 秒来创建结果文件。 运行 查找代码用了大约 0.2 秒。使用 3 个字符进行索引可将时间减半至 0.1 秒,加速超过 150 倍。将 values 大小限制为超过 10,000 将时间从 137 秒降至 0.267 秒,加速超过 500 倍(使用 3 个字符索引)。

您可以使用

activeCells 创建 values
var values = activeCells.Select(a => a.Name).ToList();

然后使用此代码:

var possibles = values.ToLookup(v => v.Substring(0, 2));
using (FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
    using (StreamReader sr = new StreamReader(fs)) {
        using (var writer = File.CreateText(tempFile)) {
            while (!sr.EndOfStream) {
                var line = sr.ReadLine();
                var index = line.Substring(0, 2);
                foreach (var value in possibles[index]) {
                    if (line.StartsWith(value)) {
                        writer.WriteLine(line);
                    }
                }
            }
        }
    }
}