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

how to use seek() in StreamReader class?

P: n/a
We can use seek() in the FileStream class,as we know.
But I found that seek() is not work correctly in StreamReader.
Who can tell me how to use seek() correctly in StreamReader?
thanks a lot!
I use the seek() like this:
StreamReader r;
.......
r.BaseStream.seek(.....);

Nov 16 '05 #1
Share this Question
Share on Google+
11 Replies


P: n/a
Tiger,

Try calling r.DiscardBufferedData() to clear the stream's buffer of data.
If you continue to have problems please post your code and exactly what you
want to accomplish.

Hope this helps.
Nov 16 '05 #2

P: n/a
Brian Brown,
My code is like this:
FileStream fs;
fs=new FileStream("cc.txt",FileMode.Open,FileAccess.Read) ;
StreamReader r=new StreamReader(fs);
Console.WriteLine((char)r.Peek());
//r.DiscardBufferedData();
r.BaseStream.Seek(5,SeekOrigin.Current);
//r.DiscardBufferedData();
Console.WriteLine((char)r.Peek());
The content of cc.txt is :abcdefghijklmnop
I thought the result which is printed on sreen is:
a
f
But in fact is
a
a
why?
I have tried r.DiscardBufferedData(),which is remarked in my code,but the
result is
a
?
I hope your reply,thanks a lot!
"Brian Brown" wrote:
Tiger,

Try calling r.DiscardBufferedData() to clear the stream's buffer of data.
If you continue to have problems please post your code and exactly what you
want to accomplish.

Hope this helps.

Nov 16 '05 #3

P: n/a
Tiger,

I am glad that you posted your code. From the earlier posting I was
thinking that you had data left over in the buffer. Now I think that I see
what you are trying to accomplish. I will attempt to explain…

Seek is a method of the BaseStream (i.e. FileStream). If you call Seek(5,
SeekOrigin.Current) on the BaseStream (remember this is the FileStream not
the StreamReader…) you have moved the file pointer forward 5 places. If you
call the BaseStream.Read method you will see that the returned value is
offset 5 places from where the pointer used to be pointing.

The StreamReader has no such method as Seek. Since this is the case you will
not get the results you expect when you call StreamReader.Peek(). The Peek()
method uses a different pointer to the data. It will see the next character
in the stream according to where the StreamReader is pointing not where the
BaseStream pointer is located. I have posted some sample code below to
demonstrate my point.

I hope this helps

---------------
using System;
using System.IO;
using System.Text;

..
..
..
const String FILENAME = @"D:\cc.txt";

FileStream fs;
fs=new FileStream(FILENAME,FileMode.Open,FileAccess.Read) ;
StreamReader r=new StreamReader(fs);
Byte[] myByteArray = new Byte[1];
ASCIIEncoding myEncoding = new ASCIIEncoding();

//call seek on the base stream (i.e. the filestream)
r.BaseStream.Seek(0,SeekOrigin.Begin);
//read the first character from the file stream
r.BaseStream.Read(myByteArray,0,1);
//output to the console
Console.WriteLine(myEncoding.GetString(myByteArray ));

//call seek on the base stream and move it up 5 places
r.BaseStream.Seek(5,SeekOrigin.Current);
//read the first character from the file stream
r.BaseStream.Read(myByteArray,0,1);
//output to the console
Console.WriteLine(myEncoding.GetString(myByteArray ));

//close the streams
r.Close();
fs.Close();

Nov 16 '05 #4

P: n/a
Tiger <Ti***@discussions.microsoft.com> wrote:
Brian Brown,
My code is like this:
FileStream fs;
fs=new FileStream("cc.txt",FileMode.Open,FileAccess.Read) ;
StreamReader r=new StreamReader(fs);
Console.WriteLine((char)r.Peek());
//r.DiscardBufferedData();
r.BaseStream.Seek(5,SeekOrigin.Current);
//r.DiscardBufferedData();
Console.WriteLine((char)r.Peek());


<snip>

Just to explain in a slightly different way to Brian (maybe).

When you first call r.Peek(), the StreamReader is reading a chunk of
data from the stream. That leaves the stream positioned later in the
data than you'd expect - at the end of the file, in your particular
case. You're then telling the stream to reposition itself 5 bytes later
- i.e. still at the end of the file. You're then telling the
StreamReader to discard the buffered data (assuming you've removed the
comment), and it then tries to read from the stream, and finds out it's
at the end of the file.

So, if you change your SeekOrigin.Current to SeekOrigin.Begin you'll
end up with

a
f

instead. It does mean you need to keep track of where you want to go to
rather than using SeekOrigin.Current, unfortunately - if you just want
to skip five characters, then using StreamReader.Read (remembering to
use the return value to find out how many characters you've actually
read) is probably easier.

--
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
Thanks a lot,Brian Brown and Jon Skeet!
So there's no way to use r.BaseStream.seek() cerrectly?
I used the seek() in another app like this
StreamReader r=new StreamReader(filename);
....
r.BaseStream.seek();
I hope to move file pointer,so seek() method is not fit here.
Could you tell me any other way to move file pointer in StreamReader?

"Brian Brown" wrote:
Tiger,

I am glad that you posted your code. From the earlier posting I was
thinking that you had data left over in the buffer. Now I think that I see
what you are trying to accomplish. I will attempt to explain…

Seek is a method of the BaseStream (i.e. FileStream). If you call Seek(5,
SeekOrigin.Current) on the BaseStream (remember this is the FileStream not
the StreamReader…) you have moved the file pointer forward 5 places. If you
call the BaseStream.Read method you will see that the returned value is
offset 5 places from where the pointer used to be pointing.

The StreamReader has no such method as Seek. Since this is the case you will
not get the results you expect when you call StreamReader.Peek(). The Peek()
method uses a different pointer to the data. It will see the next character
in the stream according to where the StreamReader is pointing not where the
BaseStream pointer is located. I have posted some sample code below to
demonstrate my point.

I hope this helps

---------------
using System;
using System.IO;
using System.Text;

.
.
.
const String FILENAME = @"D:\cc.txt";

FileStream fs;
fs=new FileStream(FILENAME,FileMode.Open,FileAccess.Read) ;
StreamReader r=new StreamReader(fs);
Byte[] myByteArray = new Byte[1];
ASCIIEncoding myEncoding = new ASCIIEncoding();

//call seek on the base stream (i.e. the filestream)
r.BaseStream.Seek(0,SeekOrigin.Begin);
//read the first character from the file stream
r.BaseStream.Read(myByteArray,0,1);
//output to the console
Console.WriteLine(myEncoding.GetString(myByteArray ));

//call seek on the base stream and move it up 5 places
r.BaseStream.Seek(5,SeekOrigin.Current);
//read the first character from the file stream
r.BaseStream.Read(myByteArray,0,1);
//output to the console
Console.WriteLine(myEncoding.GetString(myByteArray ));

//close the streams
r.Close();
fs.Close();

Nov 16 '05 #6

P: n/a
Tiger <Ti***@discussions.microsoft.com> wrote:
Thanks a lot,Brian Brown and Jon Skeet!
So there's no way to use r.BaseStream.seek() cerrectly?
There is, but using it with SeekOrigin.Current will give unexpected
results.
I used the seek() in another app like this
StreamReader r=new StreamReader(filename);
...
r.BaseStream.seek();
I hope to move file pointer,so seek() method is not fit here.
Could you tell me any other way to move file pointer in StreamReader?


Seeking is fine, so long as you know where you want to go to relative
to the start or end of the 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 #7

P: n/a
Could you give me a example?

"Jon Skeet [C# MVP]" wrote:
Tiger <Ti***@discussions.microsoft.com> wrote:
Thanks a lot,Brian Brown and Jon Skeet!
So there's no way to use r.BaseStream.seek() cerrectly?


There is, but using it with SeekOrigin.Current will give unexpected
results.
I used the seek() in another app like this
StreamReader r=new StreamReader(filename);
...
r.BaseStream.seek();
I hope to move file pointer,so seek() method is not fit here.
Could you tell me any other way to move file pointer in StreamReader?


Seeking is fine, so long as you know where you want to go to relative
to the start or end of the 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 #8

P: n/a
Tiger <Ti***@discussions.microsoft.com> wrote:
Could you give me a example?


As I said before, just change your code (including calling
DiscardBufferedData after the seek) to use

r.BaseStream.Seek(5, SeekOrigin.Begin)

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

P: n/a
I know!
Do you mean if I want to set the file pointer,I must remember the number of
the characters which have been read???
And I must use SeekOrigin.Begin?

"Jon Skeet [C# MVP]" wrote:
Tiger <Ti***@discussions.microsoft.com> wrote:
Could you give me a example?


As I said before, just change your code (including calling
DiscardBufferedData after the seek) to use

r.BaseStream.Seek(5, SeekOrigin.Begin)

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

Nov 16 '05 #10

P: n/a
Tiger <Ti***@discussions.microsoft.com> wrote:
I know!
Do you mean if I want to set the file pointer,I must remember the number of
the characters which have been read???
And I must use SeekOrigin.Begin?


Potentially - and it gets harder if you have a multibyte character
encoding, too.

However, if you just want to skip a few characters, I'd use Read if I
were 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 #11

P: n/a
Thank you very much,Jon!
you helped me a lot!

"Jon Skeet [C# MVP]" wrote:
Tiger <Ti***@discussions.microsoft.com> wrote:
I know!
Do you mean if I want to set the file pointer,I must remember the number of
the characters which have been read???
And I must use SeekOrigin.Begin?


Potentially - and it gets harder if you have a multibyte character
encoding, too.

However, if you just want to skip a few characters, I'd use Read if I
were 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 #12

This discussion thread is closed

Replies have been disabled for this discussion.