c# 倒序读取txt文件

倒序读取txt文件,基本思路:
1.使用 FileStream 文件流,可以设置流的位置 position;
2.每次读取一行:行的标记就是两个 \n 之间的内容,占位符在流中的值为 ;
byte n = 0xD;//回车符
byte r = 0xA;//换行符
3.读取时每一行从后向前读,所以输出的字符串为倒的,故读完一行后要将内容反转;

4.倒序读行时同理,行的记录也是倒的,需要将行记录反转;


调用方法:
1.获取文件夹下的所有文件信息
var files = GetFile("c:\logs");
2.获取指定文件最后200行记录
var result = LastLog("c:\\logs\log.txt",0);
result.data ;//文件内容
result.position; //本次读取流的起始位置


主要方法:

/// <summary>
/// 获取目录下所有文件信息
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
private List<LogFileModel> GetFile(string path)
{
	List<LogFileModel> list = new List<LogFileModel>();
	var files = Directory.GetFiles(path);
	
	if (files.IsNullOrDbNull())
		return null;
	LogFileModel item;
	FileInfo f;
	Func<long, string> getFileSize = (x) =>
	{
		if (x <= 0)
			return "0KB";
		var d = Math.Round(x*1.0/1024/1024, 2);
		return string.Format("{0}KB", d);
	};
	var fileInfos = new List<FileInfo>();
	files.All(x =>
	{
		fileInfos.Add(new FileInfo(x));
		return true;
	});
	int i = 1;
	//按照创建时间倒序
	fileInfos
		.OrderByDescending(x=>x.CreationTime)
		.ToList()
		.ForEach(x =>
	{
		item = new LogFileModel
		{
			name = x.Name,
			size=x.Length,
			desc = getFileSize(x.Length)
		};

		list.Add(item);
		
		if (i++ >= 20)
			return ;
	});
	return list;
}

/// <summary>
/// 倒序读取文本文件
/// </summary>
/// <param name="file">文件路径</param>
/// <param name="position">读取流的起始位置</param>
/// <returns></returns>
public LastLogResult LastLog(string file, long position)
{
	if (!File.Exists(file))
	{
		result.msg = "文件路径无效!";
		return result;
	}
	StringBuilder txt = new StringBuilder();
	long ps = position;
	using (var fs = new FileStream(file,FileMode.Open,FileAccess.Read))
	{
		if (ps <= 0)
			ps = fs.Length;
		//读取200行
		for (int i = 0; i < 200; i++)
		{
			ps = InverseReadRow(fs, ps, ref txt);
			if (ps <= 0)
				break;
		}
	}
	result.data = txt.ToString();
	result.position = ps;
	result.success = true;
	return result;
}


/// <summary>
/// 从后向前按行读取文本文件,最多读取 10kb
/// </summary>
/// <param name="fs"></param>
/// <param name="position"></param>
/// <param name="s"></param>
/// <param name="maxRead">默认每次最多读取10kb数据</param>
/// <returns>返回读取位置</returns>
long InverseReadRow(FileStream fs
	, long position
	, ref StringBuilder s
	, int maxRead = 10240)
{
	byte n = 0xD;//回车符
	byte r = 0xA;//换行符
	if (fs.Length == 0)
		return 0;
	var newPos = position - 1;
	int curVal = 0;
	var readLength = 0;
	List<byte> arr = new List<byte>();
	var str = "";
	//bool brk = false;
	do
	{
		readLength++;
		if (newPos <= 0)
			newPos = 0;

		fs.Position = newPos;
		curVal = fs.ReadByte();
		if (curVal == -1)
			break;

		arr.Insert(0, (byte)curVal);

		if (newPos <= 0)
			break;
		//
		if (readLength == maxRead)
			break;


		if (curVal != n)
			newPos--;

	} while (curVal != n);
	str = Encoding.UTF8.GetString(arr.ToArray());
	s.Insert(0, str);

	return newPos;
}

使用的对象

public class LogFileModel
{
	public string name { set; get; }
	public long size { set; get; }
	public string desc { set; get; }
}
public class ResultModel<T>
{
	public ResultModel()
	{
		data = default(T);
	}

	public string msg { set; get; }
	public bool success
	{
		set;
		get;
	}
	public T data { set; get; }
}

public class LastLogResult : ResultModel<string>
{
	public long position { set; get; }
}



  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值