回答
如果它是一个大的文件,是否有可能只是寻找文件的结尾,并检查字符'\ n'的反向字符?我知道\ n和\ r \ n存在。我掀起了下面的代码,并在一个相当简单的文件上测试。你可以尝试对你有的文件进行测试吗?我知道我的解决方案看起来很长,但我认为你会发现它比从头开始阅读并重写整个文件要快。
public static void Truncate(string file, int lines)
{
using (FileStream fs = File.Open(file, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
fs.Position = fs.Length;
// \n \r\n (both uses \n for lines)
const int BUFFER_SIZE = 2048;
// Start at the end until # lines have been encountered, record the position, then truncate the file
long currentPosition = fs.Position;
int linesProcessed = 0;
byte[] buffer = new byte[BUFFER_SIZE];
while (linesProcessed < linesToTruncate && currentPosition > 0)
{
int bytesRead = FillBuffer(buffer, fs);
// We now have a buffer containing the later contents of the file
for (int i = bytesRead - 1; i >= 0; i--)
{
currentPosition--;
if (buffer[i] == '\n')
{
linesProcessed++;
if (linesProcessed == linesToTruncate)
break;
}
}
}
// Truncate the file
fs.SetLength(currentPosition);
}
}
private static int FillBuffer(byte[] buffer, FileStream fs)
{
if (fs.Position == 0)
return 0;
int bytesRead = 0;
int currentByteOffset = 0;
// Calculate how many bytes of the buffer can be filled (remember that we're going in reverse)
long expectedBytesToRead = (fs.Position < buffer.Length) ? fs.Position : buffer.Length;
fs.Position -= expectedBytesToRead;
while (bytesRead < expectedBytesToRead)
{
bytesRead += fs.Read(buffer, currentByteOffset, buffer.Length - bytesRead);
currentByteOffset += bytesRead;
}
// We have to reset the position again because we moved the reader forward;
fs.Position -= bytesRead;
return bytesRead;
}
由于您只在删除文件的末尾计划,似乎浪费改写一切,尤其是如果它是一个大文件和小N.当然,人们可以使论点是,如果有人想消除所有线路,然后从头到尾更高效。
谢谢你,明天我会尝试第一件事,但它看起来会做我所需要的 – 2012-03-09 05:42:55
工作得很好。感谢大家的帮助。 – 2012-03-09 06:08:53
您并不真正阅读INTO StreamReader。事实上,对于你要求的模式,根本不需要StreamReader。有System.IO.File具有有用的静态方法“readlines方法”,你可以改为利用:
IEnumerable<string> allBut = File.ReadLines(path).Reverse().Skip(5).Reverse();
以前的版本有缺陷,早在回应评论跟帖
List<string> allLines = File.ReadLines(path).ToList();
IEnumerable<string> allBut = allLines.Take(allLines.Count - 5);
你建议将整个文件作为高性能替代文件(ReadLines.Count _will_读取整个文件)? – 2012-03-09 03:34:14
你说得对。我只是通过一些定时测试来运行它。第二种方法始终更快。谢谢。更新我的答案以删除第一个选项。 – xcud 2012-03-09 03:47:27
+1 - 虽然通过在查找Chr(13) - 1字节时逐字节地逐字节处理它可能会变得更高性能,但这应该仍然比替代方法快。 – 2012-03-09 03:58:13
既然你是指在文件中的行,我假设它是一个文本文件。如果你只是想获得的线,你可以阅读到一个字符串数组,像这样:
string[] lines = File.ReadAllLines(@"C:\test.txt");
或者,如果你真的需要StreamReaders工作:
using (StreamReader reader = new StreamReader(@"C:\test.txt"))
{
while (!reader.EndOfStream)
{
Console.WriteLine(reader.ReadLine());
}
}
“StreamReader”的使用应该足以假定OP正在讨论文本。 – 2012-03-09 03:32:12
我想我不确定询问问题的人是否知道他们需要StreamReader,或者只知道他们需要阅读文件并在线进行快速搜索并看到StreamReader出现。但是,是的,你是正确的 – BryanJ 2012-03-09 04:37:29
- 1. 阅读流中的第一行并将其从流中删除
- 2. 从url流问题中读取最后n行
- 3. Oledb数据读取器读取Excel文档中删除的行
- 4. 从文本中读取最后2行
- 5. 从文件中读取最后N行
- 6. 从文件中读取最后一行
- 7. 删除最后一行从的QTextEdit
- 8. Smarty读取数组中的最后x个行数
- 9. 读取和删除X线在文件
- 10. 删除表中的最后一行 - SQL
- 11. 删除表中的最后一行android
- 12. 删除句子中的最后一行
- 13. Datagridview删除最后一行
- 14. tsql - 删除最后一行
- 15. tableview删除最后一行
- 16. 从流中读取数据的最有效方式
- 17. Common Lisp:读取流的最快方式
- 18. 从嵌入式资源流中读取
- 19. 从文件读取删除文档中最后一个字符串的最后一个字母?
- 20. 如何读取输出流程类的最后一行?
- 21. 从文件中删除第一行和最后一行
- 22. 如何在时间流逝后从表中动态删除行?
- 23. 如何获取从SQL表中删除的最后一行的ID
- 24. 如何删除大文件的最后2行而不读取它
- 25. 从读取器填充的阵列中删除重复项
- 26. 从txt文件中读取并删除第一行(或最后一行)而不复制
- 27. 从文本文件中读取第5行最后一行
- 28. 如何读取python中最后几行?
- 29. 从流中删除帖子
- 30. 删除文件的最后一行
从文件末尾读取x个换行符,然后从该文件的开头读取,直到该位置。 – 2012-03-09 03:22:12
您计划从文件中读取的记录是否存在某种统一性(常见记录长度,除\ n之外的任何内容)? – 2012-03-09 03:37:53