从File.OpenRead()返回一个stream
我正在编写一个WCF服务,它将允许ASP.Net网站检索文件(基于本文 )。 我的问题是,当我返回stream,它是空白的。
为了简单起见,我将代码分离成一个简单的winforms应用程序,试图find返回stream的问题,这是代码:
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); }  这段代码的结果是buf的长度是12,587字节(文件的正确长度),但是它只包含0。 
Word文档打开没有问题,如果我尝试一下,我错过了什么明显?
你忘了寻找:
 str.CopyTo(data); data.Seek(0, SeekOrigin.Begin); // <-- missing line byte[] buf = new byte[data.Length]; data.Read(buf, 0, buf.Length); 
选项:
-   data.Seekbuild议使用data.Seek
- 
使用比较简单的 Position属性:data.Position = 0;
- 
在 MemoryStream使用ToArray调用使您的生活更简单:byte[] buf = data.ToArray();
第三个select将是我的首选方法。
 请注意,您应该有一个using语句来自动closures文件stream(也可以select使用MemoryStream ),并且为System.IO添加using指令以使代码更清晰: 
 byte[] buf; using (MemoryStream data = new MemoryStream()) { using (Stream file = TestStream()) { file.CopyTo(data); buf = data.ToArray(); } } // Use buf 
 你也可能想在Stream上创build一个扩展方法,在一个地方为你做这个,例如 
 public static byte[] CopyToArray(this Stream input) { using (MemoryStream memoryStream = new MemoryStream()) { input.CopyTo(memoryStream); return memoryStream.ToArray(); } } 
请注意,这不会closuresinputstream。
您忘记了重置内存stream的位置:
 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); } 
更新:
还有一点需要注意:通常不会忽略方法的返回值。 更强大的实现应该检查在调用返回后有多less个字节被读取:
 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)); } } 
你需要
  str.CopyTo(data); data.Position = 0; // reset to beginning byte[] buf = new byte[data.Length]; data.Read(buf, 0, buf.Length); 
 而且由于你的Test()方法模仿客户端,所以应该Close()或者Dispose() str Stream。 而memoryStream也是,只是出于本质。 
尝试将您的代码更改为:
 private void Test() { System.IO.MemoryStream data = new System.IO.MemoryStream(TestStream()); byte[] buf = new byte[data.Length]; data.Read(buf, 0, buf.Length); }