【问题标题】:Reading last symbol from text file using C# [duplicate]使用C#从文本文件中读取最后一个符号[重复]
【发布时间】:2013-10-07 08:07:27
【问题描述】:

使用 C# 读取大型文本文件的最后一个符号或行的最有效方法是什么?

【问题讨论】:

  • 文件有多大?
  • +1 表示问题。看看有多少种方法可以真正给猫剥皮,这很有趣。

标签: c# file-io


【解决方案1】:

假设您的文本文件是 ASCII,此方法将允许您直接跳转到最后一个字符并避免读取文件的其余部分(就像到目前为止给出的所有其他答案一样)。

using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
    stream.Seek(-1, SeekOrigin.End);
    byte b = (byte)stream.ReadByte();
    char c = (char)b;
}

如果您的程序需要处理多字节编码,您可能需要执行一些复杂的逻辑,如Skeet's answer 所示。但是,鉴于您的情况仅限于读取最后一个字符,您可以实现特定于您预期编码的简化版本。下面的代码适用于 UTF-8(这是当今最流行的编码)。 Seek 可能会将您的阅读器置于前一个字符的中间,但解码器会在它读取最后一个字符时从中恢复。

FileInfo fileInfo = new FileInfo(path);
int maxBytesPerChar = Encoding.UTF8.GetMaxByteCount(1);
int readLength = Math.Min(maxBytesPerChar, (int)fileInfo.Length);

using (StreamReader reader = new StreamReader(path, Encoding.UTF8))
{
    reader.DiscardBufferedData();
    reader.BaseStream.Seek(-readLength, SeekOrigin.End);

    string s = reader.ReadToEnd();
    char c = s.Last();
}

【讨论】:

  • 这看起来很有趣。 +1。这是如何“在引擎盖下”工作的?当然,它必须首先以某种方式读取整个文件才能知道最后一个字节“在哪里”?
  • @DeeMac 实际上没有任何“幕后”。它使用“.Seek()”映射到 Windows API 函数SetFilePointer()
  • @DeeMac:不会。操作系统会记录文件长度,所以每次读取都不需要遍历。
  • 明白。会记住这一点。谢谢。
【解决方案2】:

如果文件不是太大,只需阅读这些行并选择最后一行:

string lastLine = File.ReadLines("pathToFile").LastOrDefault(); // if the file is empty

所以你以这种方式得到最后一个字符:

Char lastChar = '\0';
if(lastLine  != null) lastChar = lastLine.LastOrDefault();

File.ReadLines 不需要在开始处理之前读取所有行,因此在内存消耗方面很便宜。

这是 J. Skeet 提供的更复杂的方法:How to read a text file reversely with iterator in C#

【讨论】:

  • 它只会选择最后一行而不是最后一个符号!!
  • @NeelBhatt: 已经编辑了:)
  • 哦,好吧,对不起 :) 但你确定 lastline.Last() 会给出最后一个字符吗?因为我对此有些怀疑!
  • @NeelBhatt 为什么不试试呢?那应该工作。顺便说一句,如果您的文件不包含任何行,这将抛出 InvalidOperationException 照顾好这个
  • 哦,是的,我还没有尝试过,所以这就是它对我造成怀疑的原因,但无论如何,它应该可以工作:)
【解决方案3】:
string s = File.ReadAllText("test.txt");
string[] split = s.Split(s[s.Length - 1]);

最后一行:-

var lastLine = File.ReadLines("test.txt").Last();

【讨论】:

    【解决方案4】:
    using System;
    using System.IO;
    
    class Test
    {
        public static void Main()
        {
            try
            {
                using (StreamReader sr = new StreamReader("TestFile.txt"))
                {
                    String line = sr.ReadToEnd();
                    Console.WriteLine(line[line.length-1);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("The file could not be read:");
                Console.WriteLine(e.Message);
            }
        }
    }
    

    【讨论】:

      【解决方案5】:

      我建议使用 File-Class 的 ReadToEnd-Method,所以你不需要关闭 Steam/TextReader:

      string s = File.ReadAllText(@"YOUR PATH HERE");
      char lastchar = s[s.Length - 1];
      

      【讨论】:

        【解决方案6】:

        禁食法:

        var lines = new ReverseLineReader(filename);
        var last = lines.Take(1);
        

        您可以阅读更多Here

        【讨论】:

          猜你喜欢
          • 2018-07-15
          • 2010-09-06
          • 2019-05-26
          • 2023-03-09
          • 2013-07-04
          • 2013-06-28
          • 1970-01-01
          相关资源
          最近更新 更多