2010-07-09 3 views
40

У меня есть следующий метод-конструктор, который открывает MemoryStream из файла пути:Как получить MemoryStream из потока в .NET?

MemoryStream _ms; 

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

мне нужно изменить, чтобы принять Stream вместо пути к файлу. Какой самый простой/самый эффективный способ получить MemoryStream от объекта Stream?

+3

Как только у вас есть Stream, зачем его конвертировать в MemoryStream? Не можете ли вы просто работать с Stream напрямую? –

+1

Мне нужен MemoryStream из-за других зависимостей. – fearofawhackplanet

ответ

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

+0

@fearofawhackplanet - Правильно. Я немного удался. Исправлена. –

+3

выглядит как одна закрывающая скобка отсутствует. должно быть 'while ((read = input.Read (buffer, 0, buffer.Length))> 0)' –

2

How do I copy the contents of one stream to another?

видеть. принять поток и скопировать в память. вы не должны использовать .Length только для Stream, потому что это не обязательно реализуется в каждом конкретном потоке.

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.