我写了这个小程序,它从Random.txt读取每第5个字符 在random.txt中,我有一行文字:ABCDEFGHIJKLMNOPRST。我得到了预期的结果:
以下是代码:
static void Main(string[] args)
{
StreamReader fp;
int n;
fp = new StreamReader("d:\\RANDOM.txt");
long previousBSposition = fp.BaseStream.Position;
//In this point BaseStream.Position is 0, as expected
n = 0;
while (!fp.EndOfStream)
{
//After !fp.EndOfStream were executed, BaseStream.Position is changed to 19,
//so I have to reset it to a previous position :S
fp.BaseStream.Seek(previousBSposition, SeekOrigin.Begin);
Console.WriteLine("Position of " + Convert.ToChar(fp.Read()) + " is " + fp.BaseStream.Position);
n = n + 5;
fp.DiscardBufferedData();
fp.BaseStream.Seek(n, SeekOrigin.Begin);
previousBSposition = fp.BaseStream.Position;
}
}
我的问题是,为什么在while (!fp.EndOfStream)
BaseStream.Position
行更改为19之后,例如BaseStream
的结尾。当我打电话BaseStream.Position
检查时,我预计EndOfStream
会保持不变,显然是错误的吗?
感谢。
答案 0 :(得分:4)
确定Stream
是否在其末尾的唯一方法是实际从中读取内容并检查返回值是否为0.(StreamReader
有另一种方式 - 检查其内部缓冲区,但你正确地不要通过调用DiscardBufferedData
来实现这一点。)
因此,EndOfStream
必须从基本流中读取至少一个字节。而且,由于逐字节读取效率低下,因此读取的内容更多。这就是为什么调用EndOfStream
将位置更改为结尾的原因(对于较大的文件,它不会是文件的结尾)。
您似乎实际上不需要使用StreamReader
,因此您应该直接使用Stream
(或具体为FileStream
):
using (Stream fp = new FileStream(@"d:\RANDOM.txt", FileMode.Open))
{
int n = 0;
while (true)
{
int read = fp.ReadByte();
if (read == -1)
break;
char c = (char)read;
Console.WriteLine("Position of {0} is {1}.", c, fp.Position);
n += 5;
fp.Position = n;
}
}
(我不确定在这种情况下设置位置超出文件末尾的位置,你可能需要为此添加一个检查。)
答案 1 :(得分:2)
基本流的Position
属性是指缓冲区中最后一个读取字节的位置,而不是StreamReader光标的实际位置。
答案 2 :(得分:1)
你是对的,我也可以重现你的问题,无论如何根据(MSDN: Read Text from a File)使用StreamReader读取文本文件的正确方法如下,而不是你的(这也总是关闭并处理流使用使用块):
try
{
// Create an instance of StreamReader to read from a file.
// The using statement also closes the StreamReader.
using (StreamReader sr = new StreamReader("TestFile.txt"))
{
String line;
// Read and display lines from the file until the end of
// the file is reached.
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
catch (Exception e)
{
// Let the user know what went wrong.
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}