2010-07-09 7 views
40

Bir MemoryStream dosyasını bir dosya yolundan açan aşağıdaki kurucu yöntemim var:NET'te bir akışından MemoryStream nasıl alınır?

MemoryStream _ms; 

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

Bir dosya yolu yerine Stream kabul etmek için bunu değiştirmem gerekiyor. Xzx18 nesnesinden MemoryStream elde etmenin en kolay/en etkili yolu nedir?

+3

Akışa sahip olduğunuzda, neden bunu bir MemoryStream'e dönüştürmekten çekinmiyorsunuz? Akışla doğrudan çalışamaz mısın? –

+1

Diğer bağımlılıklardan dolayı bir MemoryStream'e ihtiyacım var. – fearofawhackplanet

cevap

18

Sınıfınızı bir dosya adı yerine bir Akışı kabul edecek şekilde değiştiriyorsanız, bir MemoryStream öğesine dönüştürmeyi zahmet etmeyin. altında yatan Akış işlemleri halletsin:

public class MyClass 
{ 
    Stream _s; 

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

Ama gerçekten iç operasyonları için bir MemoryStream gerekiyorsa, MemoryStream kaynak Çayı'nın dışına veri kopyalamak gerekir:

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

Süre çizgisinin sonunda '> 0' olduğunu varsayar mıyım? – fearofawhackplanet

+0

@fearofawhackplanet - Doğru. Biraz sildiğim için mutluyum. Sabit. –

+3

, bir kapatma parantezinin eksik olduğu anlaşılıyor. while ((read = input.Read (buffer, 0, buffer.Length))> 0) 'olmalıdır –

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

Aktarım nesnesindeki tüm verileri byte[] arabelleğine okuyup, bunu yapıcı aracılığıyla MemoryStream numarasına iletmeniz gerekir. Kullandığınız akış nesnesi türü hakkında daha spesifik olmak daha iyi olabilir. Stream çok geneldir ve Length özniteliğini uygulayamaz, bu da veri okurken oldukça kullanışlıdır. İşte

sizin için bazı kod:

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

Ben bu arada kullanın: Stream nesne Length niteliği uygulamak etmezse

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

    _ms = new MemoryStream(inputBuffer); 
} 

, böyle bir şey uygulamak zorunda kalacak Uzantı yöntemleri:

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'te, Diğer cevaplarda listelenen ev demleme yöntemleri yerine, bir akışı kopyalamak için Stream.CopyTo'u kullanabilir.

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

bunu kullanın:

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

Bu MemoryStream için Stream dönüştürecektir.