By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,028 Members | 1,309 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,028 IT Pros & Developers. It's quick & easy.

Reading a file backwards in C#

P: n/a
I have a log file that puts the most recent record at the bottom of the file. Each line is delimited by a \r\n

Does anyone know how to seek to the end of the file and start reading backwards?
Nov 16 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Not sure about that, but you could always read the file into an array
row-by-row and then use a loop to read it backwards.
Rick Sawtell
MCT, MCSD, MCDBA

"Neil Patel" <Neil Pa***@discussions.microsoft.com> wrote in message
news:EA**********************************@microsof t.com...
I have a log file that puts the most recent record at the bottom of the file. Each line is delimited by a \r\n
Does anyone know how to seek to the end of the file and start reading

backwards?
Nov 16 '05 #2

P: n/a
Couple of ways to do that.

Method 1:

//initialize streamreader
StreamReader myStream= new StreamReader(@"c:\myfile.txt");
//seek file pointer to end
myStream.BaseStream.Seek(1024,SeekOrigin.End);

//intialize array of size 1024
char [] arr = new char[1024];
//loop now and read backwards
While(myStream.BaseStream.Position > 0)
{
arr.Initialize();
//Move back 1024 bytes (for better control)
myStream.BaseStream.Seek(1024,SeekOrigin.Current);
//read 1024 bytes.
int bytesRead = myStream.Read(arr,0,1024);

}

Method:2

//initialize streamreader
StreamReader myStream = new StreamReader(@"c:\myfile.txt");
//read all the contents and store in string
string WholeFileString=myStream.ReadToEnd();
//convert to array
char []strArray = WholeFileString.ToCharArray();
//reverse the array
Array.Reverse(strArray);
//again convert to string
string newStr = new string(strArray);
//specify the split array (Note \r\n must be specified reverse becoz
string is reverse
char [] split = new char[2];
split[0] = '\n';
split[1] = '\r';
//receive the string array after spliting
string [] Lines = newStr.Split(split);

lines[0] = ; //last line of the file
lines[lines.Length-1] = ; //first line of the file

--
Shak
(Houston)
"Neil Patel" <Neil Pa***@discussions.microsoft.com> wrote in message
news:EA**********************************@microsof t.com...
I have a log file that puts the most recent record at the bottom of the file. Each line is delimited by a \r\n
Does anyone know how to seek to the end of the file and start reading

backwards?
Nov 16 '05 #3

P: n/a
Sorry some typos
myStream.BaseStream.Seek(1024,SeekOrigin.End);
this must be

myStream.BaseStream.Seek(0,SeekOrigin.End);
myStream.BaseStream.Seek(1024,SeekOrigin.Current);
this must be
myStream.BaseStream.Seek(-1024,SeekOrigin.Current);

--
Shak
(Houston)

"Shakir Hussain" <sh**@fakedomain.com> wrote in message
news:eB**************@TK2MSFTNGP11.phx.gbl... Couple of ways to do that.

Method 1:

//initialize streamreader
StreamReader myStream= new StreamReader(@"c:\myfile.txt");
//seek file pointer to end
myStream.BaseStream.Seek(1024,SeekOrigin.End);

//intialize array of size 1024
char [] arr = new char[1024];
//loop now and read backwards
While(myStream.BaseStream.Position > 0)
{
arr.Initialize();
//Move back 1024 bytes (for better control)
myStream.BaseStream.Seek(1024,SeekOrigin.Current);
//read 1024 bytes.
int bytesRead = myStream.Read(arr,0,1024);

}

Method:2

//initialize streamreader
StreamReader myStream = new StreamReader(@"c:\myfile.txt");
//read all the contents and store in string
string WholeFileString=myStream.ReadToEnd();
//convert to array
char []strArray = WholeFileString.ToCharArray();
//reverse the array
Array.Reverse(strArray);
//again convert to string
string newStr = new string(strArray);
//specify the split array (Note \r\n must be specified reverse becoz
string is reverse
char [] split = new char[2];
split[0] = '\n';
split[1] = '\r';
//receive the string array after spliting
string [] Lines = newStr.Split(split);

lines[0] = ; //last line of the file
lines[lines.Length-1] = ; //first line of the file

--
Shak
(Houston)
"Neil Patel" <Neil Pa***@discussions.microsoft.com> wrote in message
news:EA**********************************@microsof t.com...
I have a log file that puts the most recent record at the bottom of the

file. Each line is delimited by a \r\n

Does anyone know how to seek to the end of the file and start reading

backwards?

Nov 16 '05 #4

P: n/a
Shakir Hussain <sh**@fakedomain.com> wrote:
Couple of ways to do that.

Method 1:

//initialize streamreader
StreamReader myStream= new StreamReader(@"c:\myfile.txt");
//seek file pointer to end
myStream.BaseStream.Seek(1024,SeekOrigin.End);

//intialize array of size 1024
char [] arr = new char[1024];
//loop now and read backwards
While(myStream.BaseStream.Position > 0)
{
arr.Initialize();
//Move back 1024 bytes (for better control)
myStream.BaseStream.Seek(1024,SeekOrigin.Current);
//read 1024 bytes.
int bytesRead = myStream.Read(arr,0,1024);

}
Note that you've got a bit of confusion here between bytes and
characters - a StreamReader returns the number of *characters* read,
not bytes... and that introduces another problem. There's nothing to
say that moving backwards 1024 bytes will even put you at the start of
a character - it could be in the middle of a multi-byte character.

You also need to discard the StreamReader's buffer after repositioning.

Also, the first parameter to Seek should be -1024, not 1024, otherwise
it's moving forwards not backwards.

Finally, moving back 1024 bytes doesn't mean you'll move back 1024
characters, so the code above could mean reading some characters twice.
Method:2

//initialize streamreader
StreamReader myStream = new StreamReader(@"c:\myfile.txt");
//read all the contents and store in string
string WholeFileString=myStream.ReadToEnd();
//convert to array
char []strArray = WholeFileString.ToCharArray();
//reverse the array
Array.Reverse(strArray);
//again convert to string
string newStr = new string(strArray);
//specify the split array (Note \r\n must be specified reverse becoz
string is reverse
char [] split = new char[2];
split[0] = '\n';
split[1] = '\r';
//receive the string array after spliting
string [] Lines = newStr.Split(split);

lines[0] = ; //last line of the file
lines[lines.Length-1] = ; //first line of the file


That gives every line of the file reversed as well, which probably
isn't desired. I'd suggest:

ArrayList list = new ArrayList();
using (StreamReader reader = new StreamReader(@"c:\myfile.txt")
{
string line;
while ( (line=reader.ReadLine()) != null)
{
list.Add(line);
}
}
list.Reverse();

That gives you an ArrayList of each line of the file, starting from the
end. It probably doesn't help the OP, however, as I'd assume that the
idea is to avoid having to read the whole file.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #5

P: n/a
<"=?Utf-8?B?TmVpbCBQYXRlbA==?=" <Neil
Pa***@discussions.microsoft.com>> wrote:
I have a log file that puts the most recent record at the bottom of
the file. Each line is delimited by a \r\n

Does anyone know how to seek to the end of the file and start reading
backwards?


It would be possible to have a type of stream which wrapped another
stream (a seekable one) and read it backwards. It would buffer a chunk
at a time, and offer up the contents of that buffer backwards. It
wouldn't be particularly hard to write, so long as you kept everything
nice and simple.

What's much harder is writing an Encoding which is capable of taking
that backwards stream and converting it into a backwards sequence of
characters. In some encodings it may even be impossible. For any
encoding with a fixed size, it's pretty easy. (In fact, it would be
possible to write an encoding which, given another encoding and the
fixed number of bytes per character used by that encoding, created a
backwards encoding for it.)

For UTF-8 it's possible, as you can detect when a character ends.
(Either the top two bits are set or the top bit is unset.) It's non-
trivial to write though.

The main point is you'd need to do this for each encoding you're
interested in - which encoding is the log file in? I could probably be
persuaded to help out with the backwards stream and a single encoding,
but I'm not going to start writing multiple encodings on the off-chance
that I write the one that's useful to you :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #6

P: n/a
guy
or push each row onto a stack, then you pop them off...

hth guy

(assuming you have enough ram to read the whole file)

"Rick Sawtell" wrote:
Not sure about that, but you could always read the file into an array
row-by-row and then use a loop to read it backwards.
Rick Sawtell
MCT, MCSD, MCDBA

"Neil Patel" <Neil Pa***@discussions.microsoft.com> wrote in message
news:EA**********************************@microsof t.com...
I have a log file that puts the most recent record at the bottom of the

file. Each line is delimited by a \r\n

Does anyone know how to seek to the end of the file and start reading

backwards?

Nov 16 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.