2010-07-09 38 views
40

我有打开从文件路径MemoryStream下面的构造方法:如何从.NET中的流获取MemoryStream?

MemoryStream _ms; 

public MyClass(string filePath) 
{ 
    byte[] docBytes = File.ReadAllBytes(filePath); 
    _ms = new MemoryStream(); 
    _ms.Write(docBytes, 0, docBytes.Length); 
} 

我需要改变这个接受Stream而不是文件路径。从Stream对象中获得MemoryStream最简单/最有效的方法是什么?

+3

一旦你有了Stream,为什么还要把它转换成MemoryStream呢?你不能直接使用Stream吗? – 2010-07-09 12:53:35

+1

由于其他依赖性,我需要一个MemoryStream。 – fearofawhackplanet 2010-07-09 13:17:28

回答

18

如果您正在修改您的类以接受Stream而不是文件名,请不要转换为MemoryStream。让底层流处理操作:

public class MyClass 
{ 
    Stream _s; 

    public MyClass(Stream s) { _s = s; } 
} 

但如果你真的需要为内部操作一个MemoryStream,你得出来的数据源流的复制到的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); 
    } 
} 
+0

我假设这是'> 0'在while行的结尾? – fearofawhackplanet 2010-07-09 13:19:13

+0

@fearofawhackplanet - 正确。我有点删除快乐。固定。 – 2010-07-09 13:20:20

+3

看起来像缺少一个右括号。应该是'while((read = input.Read(buffer,0,buffer.Length))> 0)' – 2013-07-15 08:41:48

1
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); 
} 
3

您必须将Stream对象中的所有数据读入byte[]缓冲区,然后通过其构造函数将其传递到MemoryStream。最好是更具体地说明你正在使用的流对象的类型。 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; 
} 
1

我用的这个组合扩展方法:

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); 
     } 
    } 
148

在.NET 4中,你可以使用Stream.CopyTo来复制流,而不是其他答案中列出的自制方法。

MemoryStream _ms; 

public MyClass(Stream sourceStream) 

    _ms = new MemoryStream(); 
    sourceStream.CopyTo(_ms); 
} 
0
byte[] fileData = null; 
using (var binaryReader = new BinaryReader(Request.Files[0].InputStream)) 
{ 
    fileData = binaryReader.ReadBytes(Request.Files[0].ContentLength); 
} 
18

使用此:

var memoryStream = new MemoryStream(); 
stream.CopyTo(memoryStream); 

这将Stream转换为MemoryStream