2008-09-16 22 views

答えて

411

このサンプルでは、​​文字列を読み込んでMemoryStreamに書き込む方法を示します。


Imports System.IO 

Module Module1 
    Sub Main() 
    ' We don't need to dispose any of the MemoryStream 
    ' because it is a managed object. However, just for 
    ' good practice, we'll close the MemoryStream. 
    Using ms As New MemoryStream 
     Dim sw As New StreamWriter(ms) 
     sw.WriteLine("Hello World") 
     ' The string is currently stored in the 
     ' StreamWriters buffer. Flushing the stream will 
     ' force the string into the MemoryStream. 
     sw.Flush() 
     ' If we dispose the StreamWriter now, it will close 
     ' the BaseStream (which is our MemoryStream) which 
     ' will prevent us from reading from our MemoryStream 
     'sw.Dispose() 

     ' The StreamReader will read from the current 
     ' position of the MemoryStream which is currently 
     ' set at the end of the string we just wrote to it. 
     ' We need to set the position to 0 in order to read 
     ' from the beginning. 
     ms.Position = 0 
     Dim sr As New StreamReader(ms) 
     Dim myStr = sr.ReadToEnd() 
     Console.WriteLine(myStr) 

     ' We can dispose our StreamWriter and StreamReader 
     ' now, though this isn't necessary (they don't hold 
     ' any resources open on their own). 
     sw.Dispose() 
     sr.Dispose() 
    End Using 

    Console.WriteLine("Press any key to continue.") 
    Console.ReadKey() 
    End Sub 
End Module 
+3

StreamWriterを破棄しないのですか?とにかく機能が範囲外に出る? –

+12

変数が有効範​​囲外になるとDisposeは呼び出されません。 GCがそれに近づくとFinalizeが呼び出されますが、Disposeは変数がスコープから外れる前に呼び出されなければならないものです。 StreamWriterとStreamReaderの実装がDisposeを呼び出す必要がないことを知っているので、上には呼び出さず、呼び出しを基本ストリームに渡します。しかし、IDisposableを実装しているものについてはDiposeを呼び出すための正当な議論がなされる可能性があります。将来のリリースではそれが破棄される必要がないと保証できないからです。 – Brian

+11

@MichaelEakins質問がVB.Netとしてタグ付けされているときに、なぜC#で答える必要がありますか? –

32

使用StreamReaderは、その後、あなたは文字列を返すReadToEnd方法を使用することができます。

+10

'Basestream'は、' 'memoryStream.Position = 0;' 'のように、その位置を0に設定すべきです。 –

96

StreamReaderを使用してMemoryStreamをStringに変換します。

<Extension()> _ 
Public Function ReadAll(ByVal memStream As MemoryStream) As String 
    ' Reset the stream otherwise you will just get an empty string. 
    ' Remember the position so we can restore it later. 
    Dim pos = memStream.Position 
    memStream.Position = 0 

    Dim reader As New StreamReader(memStream) 
    Dim str = reader.ReadToEnd() 

    ' Reset the position so that subsequent writes are correct. 
    memStream.Position = pos 

    Return str 
End Function 
+3

位置を0に設定すると、メソッドの再利用能力が制限されます。呼び出し元にこれを管理させるのが最善です。ストリームに文字列より前のデータが含まれている場合、呼び出し元が処理方法を知っている場合はどうなりますか? –

+1

usingステートメントは、StreamReaderが破棄されることを保証しますが、StreamReaderは、ストリームが破棄されたときに、そのストリームを閉じます。したがって、あなたのメソッドは、渡されたMemoryStreamを閉じます。これは、たとえ私がMemoryStream.Disposeが大したことをしなくても、呼び出し元のために概念的には非公開です。 – Trillian

+0

あなたは正しいです。ストリームヘルパークラスでDisposeメソッドを使用することは、特にストリームがメソッドとしてパラメータとして渡される場合は、一般的には好ましくありません。私はこの答えを更新します。私はまた以下のより完全な答えを持っています。 – Brian

231

また、私はが、これはあまり効率的であるを考えていない

Encoding.ASCII.GetString(ms.ToArray()); 

を使用することができますが、私はそれに誓うことができませんでした。また、別のエンコーディングを選択できますが、StreamReaderを使用する場合はパラメータとして指定する必要があります。ブライアンの答えの

+19

+1:単体テストの目的のために、ありがとう。 – rsenna

+6

エンコーディングはSystem.Text名前空間にあります – northben

+1

私はこれと同等のPowerShellを探していましたが、これを使用しなければなりませんでした。 ([System.Text.Encoding] :: ASCII).GetString(ms.ToArray()) – Lewis

5

A少し変更したバージョンが読んスタートのオプションの管理を可能にする、これが最も簡単な方法のようです。おそらく最も効率的ではありませんが、理解しやすく使いやすくなります。

Public Function ReadAll(ByVal memStream As MemoryStream, Optional ByVal startPos As Integer = 0) As String 
    ' reset the stream or we'll get an empty string returned 
    ' remember the position so we can restore it later 
    Dim Pos = memStream.Position 
    memStream.Position = startPos 

    Dim reader As New StreamReader(memStream) 
    Dim str = reader.ReadToEnd() 

    ' reset the position so that subsequent writes are correct 
    memStream.Position = Pos 

    Return str 
End Function 
+3

ブライアンには全く新しいものはありません。 –

17

以前のソリューションは、エンコードが関係する場合は機能しませんでした。ここにある - 「実生活」のようなもの - これを適切に行うための方法の例...この場合

using(var stream = new System.IO.MemoryStream()) 
{ 
    var serializer = new DataContractJsonSerializer(typeof(IEnumerable<ExportData>), new[]{typeof(ExportData)}, Int32.MaxValue, true, null, false);    
    serializer.WriteObject(stream, model); 


    var jsonString = Encoding.Default.GetString((stream.ToArray())); 
} 
+0

thx、私はその特定のシナリオを探していました:) –

10

、あなたは本当に簡単な方法でMemoryStreamReadToEndメソッドを使用したい場合は、あなたがこれを使用することができますMemoryStreamをタイプに素敵な拡張メソッドをしないのはなぜ

using (MemoryStream m = new MemoryStream()) 
{ 
    //for example i want to serialize an object into MemoryStream 
    //I want to use XmlSeralizer 
    XmlSerializer xs = new XmlSerializer(_yourVariable.GetType()); 
    xs.Serialize(m, _yourVariable); 

    //the easy way to use ReadToEnd method in MemoryStream 
    MessageBox.Show(m.ReadToEnd()); 
} 
5

public static class SetExtensions 
{ 
    public static string ReadToEnd(this MemoryStream BASE) 
    { 
     BASE.Position = 0; 
     StreamReader R = new StreamReader(BASE); 
     return R.ReadToEnd(); 
    } 
} 

そして、あなたはこのような方法で、この方法を使用することができます拡張メソッドは、これを達成するには?

public static class MemoryStreamExtensions 
{ 

    static object streamLock = new object(); 

    public static void WriteLine(this MemoryStream stream, string text, bool flush) 
    { 
     byte[] bytes = Encoding.UTF8.GetBytes(text + Environment.NewLine); 
     lock (streamLock) 
     { 
      stream.Write(bytes, 0, bytes.Length); 
      if (flush) 
      { 
       stream.Flush(); 
      } 
     } 
    } 

    public static void WriteLine(this MemoryStream stream, string formatString, bool flush, params string[] strings) 
    { 
     byte[] bytes = Encoding.UTF8.GetBytes(String.Format(formatString, strings) + Environment.NewLine); 
     lock (streamLock) 
     { 
      stream.Write(bytes, 0, bytes.Length); 
      if (flush) 
      { 
       stream.Flush(); 
      } 
     } 
    } 

    public static void WriteToConsole(this MemoryStream stream) 
    { 
     lock (streamLock) 
     { 
      long temporary = stream.Position; 
      stream.Position = 0; 
      using (StreamReader reader = new StreamReader(stream, Encoding.UTF8, false, 0x1000, true)) 
      { 
       string text = reader.ReadToEnd(); 
       if (!String.IsNullOrEmpty(text)) 
       { 
        Console.WriteLine(text); 
       } 
      } 
      stream.Position = temporary; 
     } 
    } 
} 

もちろん、これらの方法を標準の方法と組み合わせて使用​​する場合は注意してください。 :)あなたが行うならば、その便利なstreamLockを同時使用のために使用する必要があります。

10

このサンプルでは、​​DataContractJsonSerializerを使用してシリアル化を使用し、一部のサーバーからクライアントに文字列を渡したMemoryStreamから文字列を読み込み、渡された文字列からMemoryStreamを復元する方法を示します次に、MemoryStreamを逆シリアル化します。

私は、このサンプルを実行するために、異なるポストの部分を使用しました。

これが役立つことを願っています。

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Runtime.Serialization; 
using System.Runtime.Serialization.Json; 
using System.Threading; 

namespace JsonSample 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var phones = new List<Phone> 
      { 
       new Phone { Type = PhoneTypes.Home, Number = "28736127" }, 
       new Phone { Type = PhoneTypes.Movil, Number = "842736487" } 
      }; 
      var p = new Person { Id = 1, Name = "Person 1", BirthDate = DateTime.Now, Phones = phones }; 

      Console.WriteLine("New object 'Person' in the server side:"); 
      Console.WriteLine(string.Format("Id: {0}, Name: {1}, Birthday: {2}.", p.Id, p.Name, p.BirthDate.ToShortDateString())); 
      Console.WriteLine(string.Format("Phone: {0} {1}", p.Phones[0].Type.ToString(), p.Phones[0].Number)); 
      Console.WriteLine(string.Format("Phone: {0} {1}", p.Phones[1].Type.ToString(), p.Phones[1].Number)); 

      Console.Write(Environment.NewLine); 
      Thread.Sleep(2000); 

      var stream1 = new MemoryStream(); 
      var ser = new DataContractJsonSerializer(typeof(Person)); 

      ser.WriteObject(stream1, p); 

      stream1.Position = 0; 
      StreamReader sr = new StreamReader(stream1); 
      Console.Write("JSON form of Person object: "); 
      Console.WriteLine(sr.ReadToEnd()); 

      Console.Write(Environment.NewLine); 
      Thread.Sleep(2000); 

      var f = GetStringFromMemoryStream(stream1); 

      Console.Write(Environment.NewLine); 
      Thread.Sleep(2000); 

      Console.WriteLine("Passing string parameter from server to client..."); 

      Console.Write(Environment.NewLine); 
      Thread.Sleep(2000); 

      var g = GetMemoryStreamFromString(f); 
      g.Position = 0; 
      var ser2 = new DataContractJsonSerializer(typeof(Person)); 
      var p2 = (Person)ser2.ReadObject(g); 

      Console.Write(Environment.NewLine); 
      Thread.Sleep(2000); 

      Console.WriteLine("New object 'Person' arrived to the client:"); 
      Console.WriteLine(string.Format("Id: {0}, Name: {1}, Birthday: {2}.", p2.Id, p2.Name, p2.BirthDate.ToShortDateString())); 
      Console.WriteLine(string.Format("Phone: {0} {1}", p2.Phones[0].Type.ToString(), p2.Phones[0].Number)); 
      Console.WriteLine(string.Format("Phone: {0} {1}", p2.Phones[1].Type.ToString(), p2.Phones[1].Number)); 

      Console.Read(); 
     } 

     private static MemoryStream GetMemoryStreamFromString(string s) 
     { 
      var stream = new MemoryStream(); 
      var sw = new StreamWriter(stream); 
      sw.Write(s); 
      sw.Flush(); 
      stream.Position = 0; 
      return stream; 
     } 

     private static string GetStringFromMemoryStream(MemoryStream ms) 
     { 
      ms.Position = 0; 
      using (StreamReader sr = new StreamReader(ms)) 
      { 
       return sr.ReadToEnd(); 
      } 
     } 
    } 

    [DataContract] 
    internal class Person 
    { 
     [DataMember] 
     public int Id { get; set; } 
     [DataMember] 
     public string Name { get; set; } 
     [DataMember] 
     public DateTime BirthDate { get; set; } 
     [DataMember] 
     public List<Phone> Phones { get; set; } 
    } 

    [DataContract] 
    internal class Phone 
    { 
     [DataMember] 
     public PhoneTypes Type { get; set; } 
     [DataMember] 
     public string Number { get; set; } 
    } 

    internal enum PhoneTypes 
    { 
     Home = 1, 
     Movil = 2 
    } 
} 
8
byte[] array = Encoding.ASCII.GetBytes("MyTest1 - MyTest2"); 
MemoryStream streamItem = new MemoryStream(array); 

// convert to string 
StreamReader reader = new StreamReader(streamItem); 
string text = reader.ReadToEnd(); 
関連する問題