2012-05-04 10 views
31

Ich versuche, ein Objekt in eine Xml-Zeichenfolge zu schreiben und diese Zeichenfolge und speichern Sie es in eine DB. Aber zuerst muss ich die Zeichenfolge ...Lesen aus dem Speicher-Stream in Zeichenfolge

private static readonly Encoding LocalEncoding = Encoding.UTF8; 

    public static string SaveToString<T> (T settings) 
    { 
     Stream stream = null; 
     TextWriter writer = null; 
     string settingsString = null; 

     try 
     { 
      stream = new MemoryStream(); 

      var serializer = new XmlSerializer(typeof(T)); 

      writer = new StreamWriter(stream, LocalEncoding); 

      serializer.Serialize(writer, settings); 

      var buffer = new byte[stream.Length]; 

      stream.Read(buffer, 0, (int)stream.Length); 

      settingsString = LocalEncoding.GetString(buffer); 
     } 
     catch(Exception ex) 
     { 
      // If the action cancels we don't want to throw, just return null. 
     } 
     finally 
     { 
      if (stream != null) 
       stream.Close(); 

      if(writer != null) 
       writer.Close(); 
     } 

     return settingsString; 
    } 

Dies scheint zu funktionieren, wird der Stream mit Bytes gefüllt. Aber wenn ich es wieder in den Puffer und dann in die Zeichenfolge lese ... wird der Puffer mit '0' gefüllt! Nicht sicher, was ich hier falsch mache Jungs.

+1

möglich Duplikat [Wie Sie eine Zeichenfolge aus einem Memorystream erhalten Sie?] (Http://stackoverflow.com/questions/78181/how-do-you-get-a-string-from -a-memorystream) – andyp

Antwort

64

Wenn Sie die Ergebnisse von stream.Read überprüft hätten, hätten Sie gesehen, dass es nichts gelesen hat - weil Sie den Stream nicht zurückgespult haben. (Sie können dies tun, mit stream.Position = 0;.) Allerdings ist es einfacher, nur ToArray zu nennen:

settingsString = LocalEncoding.GetString(stream.ToArray()); 

(Sie werden die Art der stream von Stream zu MemoryStream ändern müssen, aber das ist in Ordnung, wie es in der gleichen Methode ist wo Sie es erstellen.)

Alternativ - und noch einfacher - verwenden Sie einfach StringWriter statt StreamWriter. Sie müssen eine Unterklasse erstellen, wenn Sie UTF-8 anstelle von UTF-16 verwenden möchten, aber das ist ziemlich einfach. Ein Beispiel finden Sie in this answer.

Ich bin besorgt über die Art und Weise, wie Sie nur Exception und unter der Annahme fangen, dass es übrigens etwas harmlos bedeutet - ohne überhaupt etwas protokollieren. Beachten Sie, dass using Anweisungen im Allgemeinen sauberer sind als das Schreiben expliziter finally Blöcke.

+0

Danke :). Das ist schnelle Arbeit. Ich weiß, dass die verwendeten Blöcke üblicher sind. Aber ich mag die Flachheit, die mir das gibt, keine verschachtelten Usings. Was nur eine Stilsache ist. Ich wusste nicht, dass es einen StringWriter gab, scheint viel einfacher, aber ich mag die Möglichkeit, die Codierung zu spezifizieren. Ich werde dafür wahrscheinlich eine Überladung hinzufügen, anstatt eine neue Klasse. – tigerswithguitars

+0

@tigerswithguitars: Wie genau wollen Sie 'StringWriter' selbst überladen? Der Punkt der neuen Klasse ist, dass 'StringWriter' immer UTF-16 von seiner' TextWriter.Encoding' Eigenschaft zurückgibt; Die zusätzliche Klasse überschreibt nur diese Eigenschaft. –

+0

Entschuldigung, meine Formulierung war verwirrend. Ich werde meiner eigenen Methode eine Überladung hinzufügen, um die Kodierung anzugeben. – tigerswithguitars

8
string result = System.Text.Encoding.UTF8.GetString(fs.ToArray()); 
+1

Während dieses Codebeispiel möglicherweise die Frage beantworten kann, wäre es vorzuziehen, hier einige der wesentlichen Erklärungen zu der Antwort hinzuzufügen. –

+0

Was ist "Stamm" hier? Wenn eine Variable, wie hast du sie instanziiert? Gleiche Frage für 'fs'. –

+0

Der Benutzer hat versehentlich Stamm anstelle von System – Prasanth

1
string result = Encoding.UTF8.GetString((stream as MemoryStream).ToArray()); 
+0

verwendet Ich würde die Verwendung von 'as' hier fragen - es schützt Sie vor nichts. Erstens wissen Sie, dass der Stream sowieso ein 'MemoryStream' ist, und, auch wenn dies nicht der Fall ist, wird die Übergabe von' null' in 'GetString' eine Ausnahme auslösen, so dass Sie eine explizite Umwandlung an erster Stelle verwenden können. –

+1

Während dieser Code die Frage beantworten kann, verbessert ein zusätzlicher Kontext, warum und/oder wie dieser Code die Frage beantwortet, seinen langfristigen Wert. – ryanyuyu