2010-07-09 35 views
40

tôi có phương thức khởi tạo sau đó sẽ mở ra một MemoryStream từ một đường dẫn tập tin:Cách lấy MemoryStream từ luồng trong .NET?

MemoryStream _ms; 

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

tôi cần phải thay đổi điều này để chấp nhận một Stream thay vì một đường dẫn tập tin. Whats cách dễ nhất/hiệu quả nhất để có được một MemoryStream từ đối tượng Stream là gì?

+3

Khi bạn có Luồng, tại sao lại chuyển đổi nó thành MemoryStream? Bạn có thể làm việc trực tiếp với Stream không? –

+1

Tôi cần một MemoryStream do các phụ thuộc khác. – fearofawhackplanet

Trả lời

18

Nếu bạn đang sửa đổi lớp của mình để chấp nhận Luồng thay vì tên tệp, đừng bận tâm chuyển đổi sang MemoryStream. Hãy để Stream nằm dưới xử lý các hoạt động:

public class MyClass 
{ 
    Stream _s; 

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

Nhưng nếu bạn thực sự cần một MemoryStream cho các hoạt động nội bộ, bạn sẽ phải sao chép dữ liệu ra khỏi Suối nguồn vào 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

Tôi giả sử đó là '> 0' ở cuối dòng trong khi? – fearofawhackplanet

+0

@fearofawhackplanet - Đúng. Tôi có một chút xóa hạnh phúc. Đã sửa. –

+3

trông giống như một dấu đóng ngoặc đơn bị thiếu. nên là 'while ((read = input.Read (buffer, 0, buffer.Length))> 0)' –

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

Bạn sẽ phải đọc tất cả dữ liệu từ đối tượng Luồng vào bộ đệm byte[] và sau đó chuyển nó vào MemoryStream thông qua hàm tạo của nó. Nó có thể là tốt hơn để cụ thể hơn về các loại đối tượng dòng bạn đang sử dụng. Stream rất chung chung và có thể không triển khai thuộc tính Length, điều này khá hữu ích khi đọc dữ liệu.

Dưới đây là một số mã cho bạn:

public MyClass(Stream inputStream) { 
    byte[] inputBuffer = new byte[inputStream.Length]; 
    inputStream.Read(inputBuffer, 0, inputBuffer.Length); 

    _ms = new MemoryStream(inputBuffer); 
} 

Nếu đối tượng Stream không thực hiện các thuộc tính Length, bạn sẽ phải thực hiện một cái gì đó như thế này:

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

tôi sử dụng kết hợp này các phương thức mở rộng:

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

Trong .NET 4, bạn có thể sử dụng Stream.CopyTo để sao chép luồng thay vì các phương pháp pha chế tại nhà được liệt kê trong các câu trả lời khác.

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

Sử dụng này:

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

này sẽ chuyển đổi Stream để MemoryStream.

Các vấn đề liên quan