I have a very long text file. All rows have the same length. I want to read in C# the millionth line without first reading the previous 999999 lines because otherwise the program becomes too slow. How can I do?
Asked
Active
Viewed 671 times
3 Answers
19
Try this
const int BYTES_PER_LINE = 120;
static void Main(string[] args)
{
StreamReader reader = new StreamReader("FileName", Encoding.UTF8);
long skipLines = 999999;
reader.BaseStream.Position = skipLines * BYTES_PER_LINE;
}
-
make sure you include the return for each line which may be 0x0D and/or 0x0A. Normally I set skip lines for 1 and test before using a larger number. – jdweng Jun 08 '15 at 00:36
6
Do you know the number of bytes in each line?
NB Knowing the number of characters is not sufficient.
If you know it's a fixed number of bytes use:
using( Stream stream = File.Open(fileName, FileMode.Open) )
{
stream.Seek(bytesPerLine * (myLine - 1), SeekOrigin.Begin);
using( StreamReader reader = new StreamReader(stream) )
{
string line = reader.ReadLine();
}
}
if not, then:
string line = File.ReadLines(FileName).Skip(999999).Take(1).First();
While this second option still requires the lines to be enumerated, it avoids reading the whole file into memory all at once in order to do so.
Of course, if by the millionth line you really mean the end of the file, a different approach would make sense. Find the size of the file, and use that to read lines off the end.

Tom
- 7,994
- 8
- 45
- 62
-
8Please provide explanation how this code solves "without first reading the previous 999999"? – Alexei Levenkov Jun 08 '15 at 00:15
-
1This is a horrible answer. Your example reads all of the lines in to memory, then skips 999,999 of the items in memory so it can Take 1 piece of it. You do a `Take` followed by a `First`. If you're doing a `First`, then omit the `Take(1)` piece. Either way, your answer does the exact opposite of what the OP asked. – Johnathon Sullinger Jun 08 '15 at 05:28
-
1
2
streamReader.BaseStream.Seek(skip_lines_offset, SeekOrigin.Begin);
string line = streamReader.ReadLine();
Seek
method avoids reading the whole file. You can read more here. skip_lines_offset
is the byte offset of the line, so number_of_skipped_lines * bytes_In_Line

voytek
- 2,202
- 3
- 28
- 44
-
1Generally, answers are much more helpful if they include an explanation of what the code is intended to do, and why that solves the problem without introducing others. (This post was flagged by at least one user, presumably because they thought an answer without explanation should be deleted.) – Nathan Tuggy Jun 08 '15 at 01:17