3

我对 C# 很陌生,所以请多多包涵。我正在读取(使用 FileStream)数据(固定大小)到小数组,处理数据然后再次读取,依此类推到文件末尾。

我想过使用这样的东西:

            byte[] data = new byte[30];
            int numBytesToRead = (int)fStream.Length;
            int offset = 0;

            //reading
            while (numBytesToRead > 0)
            {
                fStream.Read(data, offset, 30);
                offset += 30;
                numBytesToRead -= 30;

                //do something with the data
            }

但是我检查了文档和他们的例子,他们说上述读取方法的返回值是:

“类型:System.Int32 读入缓冲区的总字节数。如果该字节数当前不可用,这可能小于请求的字节数,或者如果到达流的末尾,则为零。”

它们目前不可用是什么意思,在读取少量数据时是否真的会发生这种情况,或者这只是针对大量数据?如果只是大,大约有多大,因为我还会在其他一些地方以更大的块阅读。如果这种情况随时可能发生,我应该如何更改我的代码以使代码仍能有效执行?

感谢您的时间和回答。

4

4 回答 4

5

read 方法返回返回的字节数,可能小于请求的字节数。通常,当您读取文件时,您将获得您要求的所有字节(除非您到达文件末尾),但是,您不能指望它总是这样。

系统可能会在立即可用的数据和需要时间检索的数据之间产生差异,以便它会立即返回当前可用的数据,开始在后台读取更多数据并期望您请求其余数据在另一个调用中的数据。AFAIK 目前没有这样做,但这是一个合理的未来场景。

您应该获得该Read方法的结果并使用它来确定您获得了多少数据。您不应该将其读入位于 的缓冲区中offset,那么您将无法读取大于缓冲区的文件。或者,您可以声明一个数组来保存整个流,然后将数据读入offset.

您还应该处理Read方法返回零的情况,这意味着没有更多数据要读取。这通常不会在您到达文件末尾之前发生,但如果它会,它会将您的代码放入一个永恒的循环中。

byte[] data = new byte[30];
int numBytesToRead = (int)fStream.Length;
int offset = 0;

//reading
while (numBytesToRead > 0) {
  int len = fStream.Read(data, 0, data.Length);
  offset += len;
  numBytesToRead -= len;
  if (len == 0 && numBytesToRead > 0) {
    // error: unexpected end of file
  }
  //do something with the data (len bytes)
}
于 2011-02-22T09:22:23.233 回答
3

尝试阅读文件中可用的内容。您可以在以下两种情况下执行此操作:

  • 您尝试读取的字节数超过文件的总长度
  • 您离文件末尾太近,无法读取您请求的字节数

此外,Stream 也有用于网络绑定连接的后代,在这些情况下,并不总是很容易知道有多少字节可用以及何时可用。

分块处理二进制文件的方法是这样的:

byte[] buffer = new byte[BUFFER_SIZE];
int inBuffer;
while ((inBuffer = stream.Read(buffer, 0, buffer.Length)) > 0)
{
    // here you have "inBytes" number of bytes in the buffer
}
于 2011-02-22T08:56:13.517 回答
1

FileStream派生自Stream, 并且Stream是一个非常通用的类,并且 Read 的描述来自该通用类。例如,流也可以是网络流,由于尚未发送,因此数据当前可能不可用。您FileStream可以假设,您将获得三种类型的返回值:

  1. 返回值==要读取的字节数(Read的最后一个参数):你在文件中间
  2. return value < count && return value > 0:您可能位于文件末尾,或者流的其余部分当前不可用。
  3. 返回值 == 0:您已经阅读了所有内容。没有什么可读的了。
于 2011-02-22T08:57:25.920 回答
1

当前不可用的字节仅适用于非 FileStream 流,例如 HttpWebRequest 中的流。

FileStream.Read 理论上可以返回 1 个字节。您应该仍然能够处理这么小的数据包。

但它永远不会返回 0,除非出现 SMB 连接丢失、文件删除、防病毒或到达文件末尾等问题。

有更好的方法来读取文件。如果您正在处理文本文件,请考虑改用 System.IO.StreamReader,因为它可以处理不同的文本编码、换行符等。

另请注意,缓冲区最大大小为 2 GB,所以不要这样做new buffer[fileStream.Length]

于 2011-02-22T09:05:03.997 回答