当使用C#中的ReadBlock方法时,如何判断是否已经到达文件末尾?

28

我发现它会一遍又一遍地返回相同的读取字符,但我想知道是否有更优雅的方法。

5个回答

56
while(!streamReader.EndOfStream)
{
    string line = streamReader.ReadLine();
    Console.WriteLine(line);
}
Console.WriteLine("End of File");

对于 TcpClient.GetStream 下面的 NetworkStream,如果远程端先终止连接,访问 EndOfStream 会导致 IOException无法从传输连接读取数据: 远程主机强制关闭了一个现有的连接。---> System.Net.Sockets.SocketException: 远程主机强制关闭了一个现有的连接 - KFL
这是一个糟糕的例子。ReadLine会阻塞,直到达到新行字符。假设你的数据会有新行字符是一个错误的假设。你的流缓冲区将会填满,你的应用程序将会挂起等待该缓冲区被读取。 - Dan
2
@Dan,你有什么建议可以替代使用ReadLine吗? - harryovers

5

请查看StreamReader.EndOfStream。当此值为true时,请停止读取循环。

确保您的代码正确处理ReadBlock调用返回的“刚刚读取的字节数”值。听起来您正在看到零字节被读取,并且只是假设您看到的未更改的缓冲区内容是同一数据的另一个读取。


2

当返回的读取长度小于你请求的读取长度时,你已经到达了文件末尾。此外,你应该跟踪读取长度,以防流大小与缓冲区大小不完全匹配,因此需要考虑缓冲区中数据的较短长度。

do{
     len = stream.ReadBlock(buffer, 0, buffer.Length);
     /* ... */
  }while(len == buffer.Length);

你也可以在循环条件中检查流的EndOfStream标志。我更喜欢这种方法,因为你不会读取长度为'0'的内容(虽然很少见,但确实可能发生)。
do{
      len = stream.ReadBlock(buffer, 0, buffer.Length);
      /* ... */
  }while(!stream.EndOfStream);

2

很抱歉,我目前还不能对答案进行评论,但是针对“The Moof”的回答...

你在这里使用cur是错误的,因为index参数是指在buffer中开始写入的索引。所以在你的示例中,应该在调用stream.ReadBlock时将其替换为0


1

MSDN了解ReadBlock()

返回值类型:System.Int32。缓冲区中读入的字符数将用于推进基础流的位置。已读取的字符数。该数字将小于或等于计数,具体取决于是否已读取所有输入字符。

因此,当返回0时,我会认为它是EOF。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接