如何缓冲输入流直到它完成

本文关键字:输入流 何缓冲 缓冲 | 更新日期: 2023-09-27 18:11:09

我正在实现一个接受图像流的WCF服务。然而,我目前得到一个异常,当我运行它。因为它试图在流完成之前获得流的长度。所以我想做的是缓冲流,直到它完成。然而,我找不到任何例子,如何做到这一点…

有人能帮忙吗?

我的代码到目前为止:

    public String uploadUserImage(Stream stream)
    {
          Stream fs = stream;
          BinaryReader br = new BinaryReader(fs);
          Byte[] bytes = br.ReadBytes((Int32)fs.Length);// this causes exception
          File.WriteAllBytes(filepath, bytes);
    }

如何缓冲输入流直到它完成

与其尝试获取长度,不如从流中读取,直到它返回"完成"为止。在。net 4中,这非常简单:

// Assuming we *really* want to read it into memory first...
MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
memoryStream.Position = 0;
File.WriteAllBytes(filepath, memoryStream);

在。net 3.5中没有CopyTo方法,但是你可以自己编写类似的东西:

public static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[8192];
    int bytesRead;
    while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        output.Write(buffer, 0, bytesRead);
    }
}

然而,现在我们已经有了复制流的东西,为什么要麻烦先把它全部读入内存呢?让我们直接把它写入一个文件:

using (FileStream output = File.OpenWrite(filepath))
{
    CopyStream(stream, output); // Or stream.CopyTo(output);
}

我不确定您返回(或不返回)什么,但这样的东西可能适合您:

public String uploadUserImage(Stream stream) {
  const int KB = 1024;
  Byte[] bytes = new Byte[KB];
  StringBuilder sb = new StringBuilder();
  using (BinaryReader br = new BinaryReader(stream)) {
    int len;
    do {
      len = br.Read(bytes, 0, KB);
      string readData = Encoding.UTF8.GetString(bytes);
      sb.Append(readData);
    } while (len == KB);
  }
  //File.WriteAllBytes(filepath, bytes);
  return sb.ToString();
}

试试这个:

    using (StreamWriter sw = File.CreateText(filepath))
    {
        stream.CopyTo(sw);
        sw.Close();
    }

Jon Skeets对。net 3.5及以下版本使用Buffer Read的回答实际上是不正确的。

缓冲区在读取之间不被清除,这可能导致任何读取返回小于8192的问题,例如,如果第二次读取读取192字节,第一次读取的最后8000字节仍然在缓冲区中,然后将返回到流。

我下面的代码你提供它一个流,它将返回一个IEnumerable数组。
使用此方法,您可以for-each它并写入MemoryStream,然后使用. getbuffer()以编译合并的字节[]结束。

private IEnumerable<byte[]> ReadFullStream(Stream stream) {
   while(true) {
        byte[] buffer = new byte[8192];//since this is created every loop, its buffer is cleared
        int bytesRead = stream.Read(buffer, 0, buffer.Length);//read up to 8192 bytes into buffer
        if (bytesRead == 0) {//if we read nothing, stream is finished
            break;
        }
        if(bytesRead < buffer.Length) {//if we read LESS than 8192 bytes, resize the buffer to essentially remove everything after what was read, otherwise you will have nullbytes/0x00bytes at the end of your buffer
            Array.Resize(ref buffer, bytesRead);
        }
        yield return buffer;//yield return the buffer data
    }//loop here until we reach a read == 0 (end of stream)
}