在 C# 中使用 ReadBlock 方法时,如何判断何时到达文件末尾?

Posted

技术标签:

【中文标题】在 C# 中使用 ReadBlock 方法时,如何判断何时到达文件末尾?【英文标题】:How can I tell when I've reached the end of the file when using the ReadBlock method in C#? 【发布时间】:2011-09-21 06:14:33 【问题描述】:

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

【问题讨论】:

【参考方案1】:
while(!streamReader.EndOfStream)

    string line = streamReader.ReadLine();
    Console.WriteLine(line);

Console.WriteLine("End of File");

【讨论】:

对于下面的NetworkStream(来自TcpClient.GetStream),如果远程端首先终止,访问EndOfStream会给我一个IOExceptionUnable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host 这是一个不好的例子。 ReadLine 将阻塞,直到到达换行符为止。这是一个错误的假设,即您的数据将具有换行符。您的流缓冲区将被填满,您的应用程序将挂起等待读取该缓冲区。 @Dan 你会建议什么作为解决方案而不是使用 ReadLine?【参考方案2】:

检查StreamReader.EndOfStream。当这是true 时停止你的读取循环。

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

【讨论】:

【参考方案3】:

不幸的是,我还不能评论答案,但要对“The Moof”的答案发表评论......

您在此处使用cur 是错误的,因为index 参数用于buffer 中开始写入的索引。因此,对于您的示例,在对 stream.ReadBlock 的调用中应将其替换为 0

【讨论】:

【参考方案4】:

当返回的读取长度小于您请求的读取长度时,您就结束了。您还应该跟踪读取长度,以防您的流大小与缓冲区大小不完全匹配,因此您需要考虑缓冲区中较短的数据长度。

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);

【讨论】:

【参考方案5】:

来自MSDN 为ReadBlock()

返回值类型:System.Int32 底层流的位置是 按字符数推进 被读入缓冲区。号码 已读取的字符数。这 数字将小于或等于 计数,取决于是否所有输入 字符已被读取。

所以我会假设它返回 0 时是 EOF,

【讨论】:

以上是关于在 C# 中使用 ReadBlock 方法时,如何判断何时到达文件末尾?的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中,当我使用该对象作为参数时,如何对该对象执行方法?

单击时如何使href链接触发C#方法

如何在 c++ 中调用 c# 方法?

为啥 C# 编译器在使用 LINQ 方法 Any() 时会创建私有 DisplayClass,我该如何避免它?

在 C# 中旋转图像时如何防止剪切?

如何从 C# 数组中删除重复项?