What is the most efficient way to read the last symbol or line of a large text file using C#?
6 Answers
Assuming your text file is ASCII, this method will allow you to jump straight to the last character and avoid reading the rest of the file (like all the other answers given so far do).
using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
stream.Seek(-1, SeekOrigin.End);
byte b = (byte)stream.ReadByte();
char c = (char)b;
}
If your program needs to handle multi-byte encodings, you might need to perform some complex logic, as shown is Skeet's answer. However, given that your case is restricted just to reading the last character, you can implement a simplified version specific to your expected encoding. The code below works for UTF-8 (which is the most popular encoding today). The Seek
may land your reader in the middle of a preceding character, but the decoder will recover from this by the time it reads the last character.
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();
}
-
This looks interesting. +1. How does this work 'under the hood'? Surely it would have to read the entirety of the file in some sort of fashion first to know 'where' the last byte is? – Oct 07 '13 at 08:23
-
@DeeMac There is not really any "under the hood". It uses ".Seek()" which maps to the Windows API function [`SetFilePointer()`](http://msdn.microsoft.com/en-us/library/windows/desktop/aa365541%28v=vs.85%29.aspx) – Matthew Watson Oct 07 '13 at 08:28
-
@DeeMac: No. The operating system records the file length, so it wouldn't need to be traversed each time it is read. – Douglas Oct 07 '13 at 08:29
-
If the file is not too large, just read the lines and pick the last:
string lastLine = File.ReadLines("pathToFile").LastOrDefault(); // if the file is empty
So you get the last character in this way:
Char lastChar = '\0';
if(lastLine != null) lastChar = lastLine.LastOrDefault();
File.ReadLines
does not need to read all lines before it can start processsing, so it's cheap in terms of memory consumption.
Here is the more complicated way from J. Skeet: How to read a text file reversely with iterator in C#

- 1
- 1

- 450,073
- 74
- 686
- 939
-
1
-
-
oh ok sorry :) but are you sure lastline.Last() will give last character? coz i have some doubt on that!! – Neel Oct 07 '13 at 08:16
-
@NeelBhatt Why not give a try? that should work. btw if your file doesn't contains any lines this is going to throw `InvalidOperationException` take care of that – Sriram Sakthivel Oct 07 '13 at 08:19
-
ohh yeah i havnt tried it ever yet so thts the reason its creating doubt for me but anyways thanx it should work then :) – Neel Oct 07 '13 at 08:21
-
@SriramSakthivel: Good point, you can use `LastOrDefault` but then you need to handle the case that `lastLine` is `null`. Edited my answer to take that into account. – Tim Schmelter Oct 07 '13 at 08:22
-
string s = File.ReadAllText("test.txt");
string[] split = s.Split(s[s.Length - 1]);
and for last line :-
var lastLine = File.ReadLines("test.txt").Last();

- 11,625
- 3
- 43
- 61
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);
}
}
}
I'd suggest to use the ReadToEnd-Method of the File-Class, so you don't need to close the Steam/TextReader:
string s = File.ReadAllText(@"YOUR PATH HERE");
char lastchar = s[s.Length - 1];

- 5,195
- 6
- 40
- 55
Fastes method:
var lines = new ReverseLineReader(filename);
var last = lines.Take(1);
You can read more Here

- 1
- 1

- 3,392
- 3
- 27
- 42