2012-05-04 8 views
31

Sto cercando di scrivere un oggetto su una stringa Xml e prendere quella stringa e salvarla in un DB. Ma prima ho bisogno di ottenere la stringa ...Lettura da flusso di memoria a stringa

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; 
    } 

Questo sembra funzionare, il flusso si riempie di byte. Ma quando vengo a leggerlo nel buffer e poi nella stringa ... il buffer è riempito con '0'! Non sono sicuro di cosa sto sbagliando qui ragazzi.

+1

possibile duplicato di [Come si ottiene una stringa da un MemoryStream?] (Http://stackoverflow.com/questions/78181/how-do-you-get-a-string-from -a-memorystream) – andyp

risposta

64

Se avessi controllato i risultati di stream.Read, avresti visto che non aveva letto nulla, perché non hai riavvolto il flusso. (Si potrebbe fare questo con stream.Position = 0;.) Tuttavia, è più facile chiamare solo ToArray:

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

(Avrai bisogno di cambiare il tipo di stream da Stream a MemoryStream, ma va bene così come è lo stesso metodo dove lo crei.)

In alternativa - e ancora più semplicemente - basta usare StringWriter anziché StreamWriter. Avrai bisogno di creare una sottoclasse se vuoi usare UTF-8 invece di UTF-16, ma è piuttosto facile. Vedi this answer per un esempio.

Sono preoccupato dal modo in cui stai catturando solo Exception e supponendo che significhi qualcosa di innocuo, a proposito - senza nemmeno registrare nulla. Si noti che le dichiarazioni using sono generalmente più pulite rispetto alla scrittura di blocchi finally espliciti.

+0

Grazie :). Questo è un lavoro veloce. So che i blocchi utilizzati sono più comuni. Ma mi piace molto la piattezza che questo mi dà, nessun uso annidato. Qual è solo una cosa di stile. Non sapevo che esistesse un StringWriter, sembra molto più facile, ma mi piace la possibilità di specificare l'encoing. Probabilmente aggiungerò un sovraccarico per questo, piuttosto che una nuova classe. – tigerswithguitars

+0

@tigerswithguitars: esattamente come intendete aggiungere un sovraccarico a 'StringWriter' stesso? Il punto della nuova classe è che 'StringWriter' restituisce sempre UTF-16 dalla sua proprietà' TextWriter.Encoding'; la classe extra sovrascrive quella proprietà. –

+0

scusa, la mia formulazione era confusa. Aggiungerò un sovraccarico al mio metodo per specificare la codifica. – tigerswithguitars

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

Sebbene questo esempio di codice possa eventualmente rispondere alla domanda, sarebbe preferibile includere alcune delle spiegazioni essenziali alla risposta qui. –

+0

Che cosa significa 'stem' qui? Se una variabile, come l'hai istanziata? La stessa domanda per 'fs'. –

+0

L'utente ha erroneamente utilizzato stem invece di System – Prasanth

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

Mi metterei in dubbio l'uso di 'as' qui - non ti protegge da nulla. In primo luogo, si sa che lo stream è comunque un 'MemoryStream', inoltre, anche se non lo fosse, passare' null' in 'GetString' genererà un'eccezione, quindi si può anche usare un cast esplicito in primo luogo. –

+1

Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo sul perché e/o su come questo codice risponde alla domanda migliora il suo valore a lungo termine. – ryanyuyu