Connecting Tech Pros Worldwide Forums | Help | Site Map

Reading a file backwards in C#

Neil Patel
Guest
 
Posts: n/a
#1: Nov 16 '05
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?

Rick Sawtell
Guest
 
Posts: n/a
#2: Nov 16 '05

re: Reading a file backwards in C#


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 Patel@discussions.microsoft.com> wrote in message
news:EA59FF94-7E38-4E33-B6F9-A1E170B18E6A@microsoft.com...[color=blue]
> I have a log file that puts the most recent record at the bottom of the[/color]
file. Each line is delimited by a \r\n[color=blue]
>
> Does anyone know how to seek to the end of the file and start reading[/color]
backwards?


Shakir Hussain
Guest
 
Posts: n/a
#3: Nov 16 '05

re: Reading a file backwards in C#


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 Patel@discussions.microsoft.com> wrote in message
news:EA59FF94-7E38-4E33-B6F9-A1E170B18E6A@microsoft.com...[color=blue]
> I have a log file that puts the most recent record at the bottom of the[/color]
file. Each line is delimited by a \r\n[color=blue]
>
> Does anyone know how to seek to the end of the file and start reading[/color]
backwards?


Shakir Hussain
Guest
 
Posts: n/a
#4: Nov 16 '05

re: Reading a file backwards in C#


Sorry some typos
[color=blue]
> myStream.BaseStream.Seek(1024,SeekOrigin.End);[/color]

this must be

myStream.BaseStream.Seek(0,SeekOrigin.End);
[color=blue]
> myStream.BaseStream.Seek(1024,SeekOrigin.Current);[/color]

this must be
[color=blue]
> myStream.BaseStream.Seek(-1024,SeekOrigin.Current);[/color]


--
Shak
(Houston)



"Shakir Hussain" <shak@fakedomain.com> wrote in message
news:eBREq15aEHA.3480@TK2MSFTNGP11.phx.gbl...[color=blue]
> 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 Patel@discussions.microsoft.com> wrote in message
> news:EA59FF94-7E38-4E33-B6F9-A1E170B18E6A@microsoft.com...[color=green]
> > I have a log file that puts the most recent record at the bottom of the[/color]
> file. Each line is delimited by a \r\n[color=green]
> >
> > Does anyone know how to seek to the end of the file and start reading[/color]
> backwards?
>
>[/color]


Jon Skeet [C# MVP]
Guest
 
Posts: n/a
#5: Nov 16 '05

re: Reading a file backwards in C#


Shakir Hussain <shak@fakedomain.com> wrote:[color=blue]
> 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);
>
> }[/color]

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.
[color=blue]
> 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[/color]

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 - <skeet@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jon Skeet [C# MVP]
Guest
 
Posts: n/a
#6: Nov 16 '05

re: Reading a file backwards in C#


<"=?Utf-8?B?TmVpbCBQYXRlbA==?=" <Neil
Patel@discussions.microsoft.com>> wrote:[color=blue]
> 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?[/color]

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 - <skeet@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
guy
Guest
 
Posts: n/a
#7: Nov 16 '05

re: Reading a file backwards in C#


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:
[color=blue]
> 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 Patel@discussions.microsoft.com> wrote in message
> news:EA59FF94-7E38-4E33-B6F9-A1E170B18E6A@microsoft.com...[color=green]
> > I have a log file that puts the most recent record at the bottom of the[/color]
> file. Each line is delimited by a \r\n[color=green]
> >
> > Does anyone know how to seek to the end of the file and start reading[/color]
> backwards?
>
>
>[/color]
Closed Thread