我正在编写一个允许ASP.Net网站检索文件的WCF服务(基于本文).我的问题是,当我返回流时,它是空白的.
为简单起见,我已将代码分离为一个简单的winforms应用程序,以尝试查找返回流的问题,这是代码:
private Stream TestStream()
{
Stream fs = File.OpenRead(@"c:\testdocument.docx");
return fs;
}
// This method converts the filestream into a byte array so that when it is
// used in my ASP.Net project the file can be sent using response.Write
private void Test()
{
System.IO.MemoryStream data = new System.IO.MemoryStream();
System.IO.Stream str = TestStream();
str.CopyTo(data);
byte[] buf = new byte[data.Length];
data.Read(buf, 0, buf.Length);
}
Run Code Online (Sandbox Code Playgroud)
这段代码的结果buf是12,587字节长(文件的正确长度),但它只包含0.
如果我尝试它,Word文档会打开没有问题,我错过了一些明显的东西吗?
ken*_*n2k 39
你忘了寻求:
str.CopyTo(data);
data.Seek(0, SeekOrigin.Begin); // <-- missing line
byte[] buf = new byte[data.Length];
data.Read(buf, 0, buf.Length);
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 15
选项:
data.Seek按照ken2k的建议使用使用稍微简单的Position属性:
data.Position = 0;
Run Code Online (Sandbox Code Playgroud)使用该ToArray调用MemoryStream可以让您的生活更简单:
byte[] buf = data.ToArray();
Run Code Online (Sandbox Code Playgroud)第三种选择是我的首选方法.
请注意,您应该有一个using语句来自动关闭文件流(以及可选的MemoryStream),并且我会添加一个using指令System.IO以使您的代码更清晰:
byte[] buf;
using (MemoryStream data = new MemoryStream())
{
using (Stream file = TestStream())
{
file.CopyTo(data);
buf = data.ToArray();
}
}
// Use buf
Run Code Online (Sandbox Code Playgroud)
您可能还想Stream在一个地方创建一个扩展方法,例如
public static byte[] CopyToArray(this Stream input)
{
using (MemoryStream memoryStream = new MemoryStream())
{
input.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这不会关闭输入流.
您忘记重置内存流的位置:
private void Test()
{
System.IO.MemoryStream data = new System.IO.MemoryStream();
System.IO.Stream str = TestStream();
str.CopyTo(data);
// Reset memory stream
data.Seek(0, SeekOrigin.Begin);
byte[] buf = new byte[data.Length];
data.Read(buf, 0, buf.Length);
}
Run Code Online (Sandbox Code Playgroud)
更新:
还有一点需要注意:通常不应忽略方法的返回值.更强大的实现应检查调用返回后读取的字节数:
private void Test()
{
using(MemoryStream data = new MemoryStream())
{
using(Stream str = TestStream())
{
str.CopyTo(data);
}
// Reset memory stream
data.Seek(0, SeekOrigin.Begin);
byte[] buf = new byte[data.Length];
int bytesRead = data.Read(buf, 0, buf.Length);
Debug.Assert(bytesRead == data.Length,
String.Format("Expected to read {0} bytes, but read {1}.",
data.Length, bytesRead));
}
}
Run Code Online (Sandbox Code Playgroud)