在C#开发中,从后向前逐行读取文件内容是一个比较常见的需求,尤其是在处理按时间顺序追加的日志文件时,我们往往需要优先查看最新的内容,这时候就需要用到文件倒序读取的相关技术。不同的文件大小和读取场景适合不同的实现方式,下面我们来逐一介绍。

方案一:先读取全部内容再倒序处理
这种方式的逻辑比较简单,先通过StreamReader把文件的所有行都读取到内存中,然后对行集合进行倒序操作,最后逐行输出即可。这种方式适合文件体积较小的场景,如果文件过大,一次性加载到内存可能会导致内存溢出。
using System;
using System.Collections.Generic;
using System.IO;
class Program
{
static void Main()
{
string filePath = "test.log";
// 判断文件是否存在
if (!File.Exists(filePath))
{
Console.WriteLine("文件不存在");
return;
}
try
{
// 读取所有行到列表
List<string> allLines = new List<string>();
using (StreamReader reader = new StreamReader(filePath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
allLines.Add(line);
}
}
// 倒序遍历输出
for (int i = allLines.Count - 1; i >= 0; i--)
{
Console.WriteLine(allLines[i]);
}
}
catch (Exception ex)
{
Console.WriteLine($"读取文件出错:{ex.Message}");
}
}
}
方案二:从文件末尾反向逐行读取
这种方式不需要一次性加载全部内容到内存,而是通过操作文件流的位置,从文件末尾开始向前查找换行符,逐行读取内容,适合处理大文件,内存占用更低。
using System;
using System.IO;
class Program
{
static void Main()
{
string filePath = "test.log";
if (!File.Exists(filePath))
{
Console.WriteLine("文件不存在");
return;
}
try
{
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
long position = fs.Length - 1;
// 如果文件为空直接返回
if (position < 0)
{
return;
}
// 存储当前读取的行内容
List<char> currentLine = new List<char>();
// 从末尾开始向前遍历
while (position >= 0)
{
fs.Seek(position, SeekOrigin.Begin);
int byteRead = fs.ReadByte();
// 如果是换行符,输出当前行
if (byteRead == 10)
{
// 跳过回车符,如果是Windows换行符的话
if (position > 0)
{
fs.Seek(position - 1, SeekOrigin.Begin);
int prevByte = fs.ReadByte();
if (prevByte == 13)
{
position--;
}
}
// 反转当前行字符并输出
currentLine.Reverse();
Console.WriteLine(new string(currentLine.ToArray()));
currentLine.Clear();
}
else
{
// 将字符加入当前行
currentLine.Add((char)byteRead);
}
position--;
}
// 处理第一行内容
if (currentLine.Count > 0)
{
currentLine.Reverse();
Console.WriteLine(new string(currentLine.ToArray()));
}
}
}
catch (Exception ex)
{
Console.WriteLine($"读取文件出错:{ex.Message}");
}
}
}
两种方案对比
我们可以通过下面的表格来对比两种方案的特点,方便根据实际场景选择:
| 对比项 | 先读全部再倒序 | 反向逐行读取 |
|---|---|---|
| 内存占用 | 较高,需要存储全部行 | 较低,仅存储当前行 |
| 适用文件大小 | 小文件 | 大文件、小文件都适用 |
| 实现复杂度 | 简单 | 较复杂 |
| 读取速度 | 小文件时较快 | 大文件时更有优势 |
注意事项
- 读取文件时要做好异常处理,避免文件被占用、权限不足等问题导致程序崩溃。
- 如果文件编码不是默认的UTF-8,需要在创建
StreamReader的时候指定对应的编码,比如new StreamReader(filePath, Encoding.GetEncoding("GBK"))。 - 反向逐行读取的方案中,换行符的处理要兼容不同系统的换行规则,Windows是rn,Linux是n,Mac是r,上面的示例仅处理了常见的n和rn的情况,实际使用时可以根据需求补充。
总结
C#中实现文件内容倒序读取主要有两种思路,一种是先加载全部内容再倒序,另一种是从文件末尾反向查找换行符逐行读取。开发者可以根据文件的大小、内存限制等实际需求选择合适的方案,小文件优先选择实现简单的第一种方案,大文件则更适合第二种低内存占用的方案。
C#文件读取倒序读取逐行读取StreamReader修改时间:2026-07-15 13:57:28