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

本文关键字:一行 文本 大型 文档 删除 查找 | 更新日期: 2023-09-27 18:15:40

我想弄清楚,如何从大型文本文档中删除特定的字符串与50万行。按内容查找行,但同时在文本文档顺序中获取当前行索引值,该值不能被打乱,以删除查找行的下一行或前一行,换句话说,按索引查找最接近的行,对于大型文档都要删除。因为我尝试过的使用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

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

写入同一个文件

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

如果您想处理非常大的文件,那么您应该使用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);
                }
            }
}

还没有测试过,但这将给出所需的方向。

让输入文件是inputFile.txt,然后您可以使用File.ReadAllLines()方法获得该特定文件中的所有行。然后使用IndexOf()方法查找该列表中特定行的索引,如果没有找到它意味着它将返回-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);