2008-09-26 8 views
16

Tengo un problema al escribir caracteres noruegos en un archivo XML usando C#. Tengo una variable de cadena que contiene texto noruego (con letras como æøå).Escribiendo archivos XML usando XmlTextWriter con codificación ISO-8859-1

estoy escribiendo el código XML utilizando un XmlTextWriter, escribir el contenido a un MemoryStream así:

MemoryStream stream = new MemoryStream(); 
XmlTextWriter xmlTextWriter = new XmlTextWriter(stream, Encoding.GetEncoding("ISO-8859-1")); 
xmlTextWriter.Formatting = Formatting.Indented; 
xmlTextWriter.WriteStartDocument(); //Start doc 

Luego añadir mi texto noruega como esto:

xmlTextWriter.WriteCData(myNorwegianText); 

Entonces escribo el archivo en el disco como este:

FileStream myFile = new FileStream(myPath, FileMode.Create); 
StreamWriter sw = new StreamWriter(myFile); 

stream.Position = 0; 
StreamReader sr = new StreamReader(stream); 
string content = sr.ReadToEnd(); 

sw.Write(content); 
sw.Flush(); 

myFile.Flush(); 
myFile.Close(); 

Ahora el problema es que en el archivo de este, todos los Norw los personajes egipcios se ven divertidos.

Probablemente estoy haciendo lo anterior de alguna manera estúpida. ¿Alguna sugerencia sobre cómo solucionarlo?

+0

Recuerde que también puede utilizar la más genérica codificación UTF-16 para escribir caracteres noruegos . –

Respuesta

13

¿Por qué está escribiendo el XML primero en un MemoryStream y luego escribiéndolo en el flujo de archivos real? Eso es bastante ineficiente. Si escribe directamente en FileStream debería funcionar.

Si aún desea hacer la doble escritura, por cualquier razón, haga una de estas dos cosas. De cualquier

  1. Asegúrese de que el StreamReader y StreamWriter objetos utiliza todo utilice el misma codificación como la que utilizó con el XmlWriter (no sólo el StreamWriter, al igual que otra persona sugerido), o

  2. No utilice StreamReader/StreamWriter. En su lugar solo copie la secuencia en el nivel de bytes utilizando un byte simple [] y Stream.Read/Write. Esto va a ser, por cierto, mucho más eficiente de todos modos.

+3

Una razón para escribir en un flujo de memoria es porque hacerlo produce una acción atómica. Eche un vistazo a este artículo para más detalles: http://aspalliance.com/1012_how_to_write_atomic_transactions_in_net – Dscoduc

3

¿Qué codificación usa para visualizar el archivo de resultados? Si no está en ISO-8859-1, no se mostrará correctamente.

¿Hay alguna razón para usar esta codificación específica, en lugar de UTF8 por ejemplo?

13

Tanto su StreamWriter como su StreamReader están utilizando UTF-8, porque no especifica la codificación. Es por eso que las cosas se corrompen.

Como dijo tomasr, usar FileStream para empezar sería más simple, pero también MemoryStream tiene el práctico método "WriteTo" que le permite copiarlo a FileStream muy fácilmente.

Espero que tenga una declaración de uso en su código real, por cierto, no desea dejar abierta la barra de herramientas de su archivo si algo sale mal mientras escribe.

Jon

7

Debe establecer la codificación cada vez que se escribe una cadena o leer datos binarios como una cadena.

Encoding encoding = Encoding.GetEncoding("ISO-8859-1"); 

    FileStream myFile = new FileStream(myPath, FileMode.Create); 
    StreamWriter sw = new StreamWriter(myFile, encoding); 

    stream.Position = 0; 
    StreamReader sr = new StreamReader(stream, encoding); 
    string content = sr.ReadToEnd(); 

    sw.Write(content); 
    sw.Flush(); 

    myFile.Flush(); 
    myFile.Close(); 
5

Como se mencionó en las respuestas anteriores, el mayor problema aquí es la Encoding, que está siendo cesación de pagos debido a que no especificada.

Cuando no especifica un Encoding para este tipo de conversión, se utiliza el valor predeterminado UTF-8, que puede coincidir o no con su situación. También está convirtiendo innecesariamente los datos al presionarlo en un MemoryStream y luego en un FileStream.

Si los datos originales no es UTF-8, lo que sucederá es que la primera transición en la MemoryStream intentará decodificar usando por defecto Encoding de UTF-8 - y corromper sus datos como resultado. Cuando escribe en el FileStream, que también usa UTF-8 como codificación de manera predeterminada, simplemente persiste en que se dañe el archivo.

Para solucionar el problema, probablemente necesite especificar Encoding en sus objetos Stream.

En realidad, puede omitir el proceso MemoryStream por completo, lo que será más rápido y más eficiente. Su código actualizado podría ser algo más como:

FileStream fs = new FileStream(myPath, FileMode.Create); 

XmlTextWriter xmlTextWriter = 
    new XmlTextWriter(fs, Encoding.GetEncoding("ISO-8859-1")); 

xmlTextWriter.Formatting = Formatting.Indented; 
xmlTextWriter.WriteStartDocument(); //Start doc 

xmlTextWriter.WriteCData(myNorwegianText); 

StreamWriter sw = new StreamWriter(fs); 

fs.Position = 0; 
StreamReader sr = new StreamReader(fs); 
string content = sr.ReadToEnd(); 

sw.Write(content); 
sw.Flush(); 

fs.Flush(); 
fs.Close(); 
+0

Si bien está correcto, la forma en que lo ha redactado es un poco confuso ya que especifica la codificación en xmltextwriter. pero como dices, no lo ha establecido en las nuevas transmisiones que creó más adelante, y con esto no lo lee de la fuente de transmisión pero revierte el valor predeterminado – MikeT

0

Después de investigar, esto es que funcionaron mejor para mí:

var doc = new XDocument(new XDeclaration("1.0", "ISO-8859-1", "")); 
     using (XmlWriter writer = doc.CreateWriter()){ 
      writer.WriteStartDocument(); 
      writer.WriteStartElement("Root"); 
      writer.WriteElementString("Foo", "value"); 
      writer.WriteEndElement(); 
      writer.WriteEndDocument(); 
     } 
     doc.Save("dte.xml"); 
Cuestiones relacionadas