2010-07-09 58 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