如何在大型文本文档中查找和删除具有下一行或上一行的特定行

How find and remove specific line with next or previous lines in large text document

我想知道如何从包含 500 000 行的大型文本文档中删除特定字符串。按内容查找行,但同时获取文本文档顺序中的当前行索引值,不得打扰,以删除找到的行的下一行或上一行,换句话说,按索引查找最近的行,以删除大文档中的两者.因为我尝试使用 File.WriteAllLines 程序的任何方法都会以这样的大小挂起。我已主动请求此文件,似乎需要找到其他方式。例如文件内容为:

1. line 1
2. line 2
3. line 3
4. line 4
5. line 5

要查找和删除的行是:

string input = "line 3" 

通过删除找到的行索引和下一行的下一行索引 + 1 来得到这个结果,如果找到的行索引号是奇数:

line 1
line 2
line 5

同时能够删除找到的行索引和索引 - 1 前一行,如果找到的行索引为偶数用于搜索字符串:

string input = "line 4" 

结果应该是:

line 1
line 2
line 5

并知道文本文档中是否不存在该行。

写入同一个文件。

让输入文件为 inputFile.txt 然后您可以使用 File.ReadAllLines() 方法获取该特定文件中的所有行。然后使用 IndexOf() 方法在该列表中查找特定行的索引,如果找不到意味着它将 return -1 然后使用 RemoveAt() 删除该行具体指标。考虑代码:

List<string> linesInFile = File.ReadAllLines(filePath).ToList(); // gives you list of lines
string input = "line 3";
int lineIndex = linesInFile.IndexOf(input);
if (lineIndex != -1)
{
    linesInFile.RemoveAt(lineIndex);
}

// If you may have more number of match for particular line means you can try this as well :

linesInFile.RemoveAll(x=> x== input);

如果你想把它写回文件意味着使用这一行:

File.WriteAllLines(filePath,linesInFile);

如果你想处理非常大的文件,你应该使用FileStream以避免将所有内容加载到内存中。

为了满足你的最后一个要求,你可以一行一行地读。它实际上使您的代码更简单。

var inputFileName = @"D:\test-input.txt";
var outputFileName = Path.GetTempFileName();

var search = "line 4";

using (var strInp = File.Open(inputFileName, FileMode.Open))
using (var strOtp = File.Open(outputFileName, FileMode.Create))
using (var reader = new StreamReader(strInp))
using (var writer = new StreamWriter(strOtp))
{
    while (reader.Peek() >= 0)
    {
        var lineOdd = reader.ReadLine();
        var lineEven = (string)null;
        if (reader.Peek() >= 0)
            lineEven = reader.ReadLine();

        if(lineOdd != search && lineEven != search)
        {
            writer.WriteLine(lineOdd);

            if(lineEven != null)
                writer.WriteLine(lineEven);
        }
    }    
}

// at this point, operation is sucessfull
// rename temp file with original one
File.Delete(inputFileName);
File.Move(outputFileName, inputFileName);

使用 System.IO.StreamReader.

private static void RemoveLines(string lineToRemove, bool skipPrevious, bool skipNext)
{
            string previousLine = string.Empty;
            string currentLine;
            bool isNext = false;
            using (StreamWriter sw = File.CreateText(@"output.txt"))
            {
                using (StreamReader sr = File.OpenText(@"input.txt"))
                {

                    while ((currentLine = sr.ReadLine()) != null)
                    {
                        if (isNext)
                        {
                            currentLine = string.Empty;
                            isNext = false;
                        }

                        if (currentLine == lineToRemove)
                        {
                            if (skipPrevious)
                            {
                                previousLine = string.Empty;
                            }

                            if (skipNext)
                            {
                                currentLine = string.Empty;
                                isNext = true;
                            }
                        }

                        if (previousLine != string.Empty && previousLine != lineToRemove)
                        {
                            sw.WriteLine(previousLine);
                        }
                        previousLine = currentLine;
                    }
                }
                if (previousLine != string.Empty && previousLine != lineToRemove)
                {
                    sw.WriteLine(previousLine);
                }
            }
}

还没有测试过,但这会给出所需的指示。