如何从.NET中的stream获取MemoryStream?
我有以下构造函数方法,从文件path打开一个MemoryStream
:
MemoryStream _ms; public MyClass(string filePath) { byte[] docBytes = File.ReadAllBytes(filePath); _ms = new MemoryStream(); _ms.Write(docBytes, 0, docBytes.Length); }
我需要改变这个接受一个Stream
而不是一个文件path。 什么是从Stream
对象获取MemoryStream
的最简单/最有效的方法?
如果你正在修改你的类接受一个stream,而不是一个文件名,不要麻烦转换成一个MemoryStream。 让底层Stream处理这些操作:
public class MyClass { Stream _s; public MyClass(Stream s) { _s = s; } }
但是,如果你真的需要一个MemoryStream来进行内部操作,你必须将数据stream从源数据stream中复制到MemoryStream中:
public MyClass(Stream stream) { _ms = new MemoryStream(); CopyStream(stream, _ms); } // Merged From linked CopyStream below and Jon Skeet's ReadFully example public static void CopyStream(Stream input, Stream output) { byte[] buffer = new byte[16*1024]; int read; while((read = input.Read (buffer, 0, buffer.Length)) > 0) { output.Write (buffer, 0, read); } }
在.NET 4中,可以使用Stream.CopyTo来复制stream,而不是其他答案中列出的自制方法。
MemoryStream _ms; public MyClass(Stream sourceStream) _ms = new MemoryStream(); sourceStream.CopyTo(_ms); }
用这个:
var memoryStream = new MemoryStream(); stream.CopyTo(memoryStream);
这将转换MemoryStream
。
您必须将Stream对象中的所有数据读入一个byte[]
缓冲区,然后通过其构造函数将其传入MemoryStream
。 最好是更具体的关于你正在使用的stream对象的types。 Stream
是非常通用的,可能不会实现Length
属性,这在读取数据时非常有用。
以下是您的一些代码:
public MyClass(Stream inputStream) { byte[] inputBuffer = new byte[inputStream.Length]; inputStream.Read(inputBuffer, 0, inputBuffer.Length); _ms = new MemoryStream(inputBuffer); }
如果Stream
对象没有实现Length
属性,则必须实现如下所示:
public MyClass(Stream inputStream) { MemoryStream outputStream = new MemoryStream(); byte[] inputBuffer = new byte[65535]; int readAmount; while((readAmount = inputStream.Read(inputBuffer, 0, inputBuffer.Length)) > 0) outputStream.Write(inputBuffer, 0, readAmount); _ms = outputStream; }
如何将一个stream的内容复制到另一个stream?
看到了。 接受一个stream并复制到内存中。 你不应该使用.Length
作为Stream
因为它不一定在每一个具体的Stream中实现。
public static void Do(Stream in) { _ms = new MemoryStream(); byte[] buffer = new byte[65536]; while ((int read = input.Read(buffer, 0, buffer.Length))>=0) _ms.Write (buffer, 0, read); }
我使用这种扩展方法的组合:
public static Stream Copy(this Stream source) { if (source == null) return null; long originalPosition = -1; if (source.CanSeek) originalPosition = source.Position; MemoryStream ms = new MemoryStream(); try { Copy(source, ms); if (originalPosition > -1) ms.Seek(originalPosition, SeekOrigin.Begin); else ms.Seek(0, SeekOrigin.Begin); return ms; } catch { ms.Dispose(); throw; } } public static void Copy(this Stream source, Stream target) { if (source == null) throw new ArgumentNullException("source"); if (target == null) throw new ArgumentNullException("target"); long originalSourcePosition = -1; int count = 0; byte[] buffer = new byte[0x1000]; if (source.CanSeek) { originalSourcePosition = source.Position; source.Seek(0, SeekOrigin.Begin); } while ((count = source.Read(buffer, 0, buffer.Length)) > 0) target.Write(buffer, 0, count); if (originalSourcePosition > -1) { source.Seek(originalSourcePosition, SeekOrigin.Begin); } }
byte[] fileData = null; using (var binaryReader = new BinaryReader(Request.Files[0].InputStream)) { fileData = binaryReader.ReadBytes(Request.Files[0].ContentLength); }