使用C#读取文本文件中的最后一个符号

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

2
文件有多大? - Tim Schmelter
+1 这个问题很有趣,因为有很多种方法可以做到同样的事情。 - user1017882
6个回答

5
假设您的文本文件是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。这是如何“在内部”工作的?它肯定必须以某种方式首先读取整个文件才能知道“最后一个字节”的位置吧? - user1017882
@DeeMac 实际上没有什么“底层”。它使用“.Seek()”,该函数映射到Windows API函数SetFilePointer() - Matthew Watson
@DeeMac:不需要每次读取文件时都遍历,因为操作系统会记录文件长度。 - Douglas
明白了,会记住的。谢谢。 - user1017882

4

1
它将选择最后一行而不是最后一个符号!! - Neel
@NeelBhatt:已经编辑好了 :) - Tim Schmelter
哦,好的抱歉 :) 但是你确定 lastline.Last() 会给出最后一个字符吗?因为我对此有些怀疑!! - Neel
@NeelBhatt 为什么不试试?那应该可以工作。顺便说一下,如果您的文件不包含任何行,这将引发“InvalidOperationException”异常,请注意处理。 - Sriram Sakthivel
我认为在你的回答中值得提及 @TimSchmelter。 - Sriram Sakthivel
显示剩余2条评论

0
string s = File.ReadAllText("test.txt");
string[] split = s.Split(s[s.Length - 1]);

而对于最后一行:-

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

0
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);
        }
    }
}

0
我建议使用File类的ReadToEnd方法,这样您就不需要关闭Steam/TextReader:
string s = File.ReadAllText(@"YOUR PATH HERE");
char lastchar = s[s.Length - 1];

-1

最快的方法:

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

你可以在这里阅读更多内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接