如何在大型文本文档中查找和删除带有下一行或上一行的特定行
本文关键字:一行 文本 大型 文档 删除 查找 | 更新日期: 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);