c# 倒序读取txt文件

曾经终败给现在 2024-02-17 17:49 110阅读 0赞

倒序读取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; //本次读取流的起始位置

主要方法:

  1. /// <summary>
  2. /// 获取目录下所有文件信息
  3. /// </summary>
  4. /// <param name="path"></param>
  5. /// <returns></returns>
  6. private List<LogFileModel> GetFile(string path)
  7. {
  8. List<LogFileModel> list = new List<LogFileModel>();
  9. var files = Directory.GetFiles(path);
  10. if (files.IsNullOrDbNull())
  11. return null;
  12. LogFileModel item;
  13. FileInfo f;
  14. Func<long, string> getFileSize = (x) =>
  15. {
  16. if (x <= 0)
  17. return "0KB";
  18. var d = Math.Round(x*1.0/1024/1024, 2);
  19. return string.Format("{0}KB", d);
  20. };
  21. var fileInfos = new List<FileInfo>();
  22. files.All(x =>
  23. {
  24. fileInfos.Add(new FileInfo(x));
  25. return true;
  26. });
  27. int i = 1;
  28. //按照创建时间倒序
  29. fileInfos
  30. .OrderByDescending(x=>x.CreationTime)
  31. .ToList()
  32. .ForEach(x =>
  33. {
  34. item = new LogFileModel
  35. {
  36. name = x.Name,
  37. size=x.Length,
  38. desc = getFileSize(x.Length)
  39. };
  40. list.Add(item);
  41. if (i++ >= 20)
  42. return ;
  43. });
  44. return list;
  45. }
  46. /// <summary>
  47. /// 倒序读取文本文件
  48. /// </summary>
  49. /// <param name="file">文件路径</param>
  50. /// <param name="position">读取流的起始位置</param>
  51. /// <returns></returns>
  52. public LastLogResult LastLog(string file, long position)
  53. {
  54. if (!File.Exists(file))
  55. {
  56. result.msg = "文件路径无效!";
  57. return result;
  58. }
  59. StringBuilder txt = new StringBuilder();
  60. long ps = position;
  61. using (var fs = new FileStream(file,FileMode.Open,FileAccess.Read))
  62. {
  63. if (ps <= 0)
  64. ps = fs.Length;
  65. //读取200行
  66. for (int i = 0; i < 200; i++)
  67. {
  68. ps = InverseReadRow(fs, ps, ref txt);
  69. if (ps <= 0)
  70. break;
  71. }
  72. }
  73. result.data = txt.ToString();
  74. result.position = ps;
  75. result.success = true;
  76. return result;
  77. }
  78. /// <summary>
  79. /// 从后向前按行读取文本文件,最多读取 10kb
  80. /// </summary>
  81. /// <param name="fs"></param>
  82. /// <param name="position"></param>
  83. /// <param name="s"></param>
  84. /// <param name="maxRead">默认每次最多读取10kb数据</param>
  85. /// <returns>返回读取位置</returns>
  86. long InverseReadRow(FileStream fs
  87. , long position
  88. , ref StringBuilder s
  89. , int maxRead = 10240)
  90. {
  91. byte n = 0xD;//回车符
  92. byte r = 0xA;//换行符
  93. if (fs.Length == 0)
  94. return 0;
  95. var newPos = position - 1;
  96. int curVal = 0;
  97. var readLength = 0;
  98. List<byte> arr = new List<byte>();
  99. var str = "";
  100. //bool brk = false;
  101. do
  102. {
  103. readLength++;
  104. if (newPos <= 0)
  105. newPos = 0;
  106. fs.Position = newPos;
  107. curVal = fs.ReadByte();
  108. if (curVal == -1)
  109. break;
  110. arr.Insert(0, (byte)curVal);
  111. if (newPos <= 0)
  112. break;
  113. //
  114. if (readLength == maxRead)
  115. break;
  116. if (curVal != n)
  117. newPos--;
  118. } while (curVal != n);
  119. str = Encoding.UTF8.GetString(arr.ToArray());
  120. s.Insert(0, str);
  121. return newPos;
  122. }

使用的对象

  1. public class LogFileModel
  2. {
  3. public string name { set; get; }
  4. public long size { set; get; }
  5. public string desc { set; get; }
  6. }
  7. public class ResultModel<T>
  8. {
  9. public ResultModel()
  10. {
  11. data = default(T);
  12. }
  13. public string msg { set; get; }
  14. public bool success
  15. {
  16. set;
  17. get;
  18. }
  19. public T data { set; get; }
  20. }
  21. public class LastLogResult : ResultModel<string>
  22. {
  23. public long position { set; get; }
  24. }

发表评论

表情:
评论列表 (有 0 条评论,110人围观)

还没有评论,来说两句吧...

相关阅读