我正在实现一个接受图像流的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)
}