2010-04-07 29 views
15

Me están enviando archivos de texto guardados en formato ISO 88591-1 que contienen caracteres acentuados del rango Latin-1 (también como ASCII az normal, etc.). ¿Cómo convierto estos archivos a UTF-8 usando C# para que los caracteres acentuados de un solo byte en ISO 8859-1 se conviertan en caracteres UTF-8 válidos?Usando .NET cómo convertir archivos de texto codificados ISO 8859-1 que contienen caracteres acentuados Latin-1 a UTF-8

He tratado de utilizar un StreamReader con ASCIIEncoding, y luego convertir la cadena ASCII en UTF-8 creando instancias de codificación y la codificación asciiutf8 y luego usando Encoding.Convert(ascii, utf8, ascii.GetBytes(asciiString)) — pero los caracteres acentuados están siendo prestados como signos de interrogación.

¿Qué paso me estoy perdiendo?

+0

¿Ha intentado utilizar un StreamWriter con codificación UTF-8 para escribir el AsciiString a cabo a una ¿Archivo de texto? ¿Eso lo hace? – Task

+0

@Task: Su problema es que nunca va a sacar la cadena de 8859-1, no es que no pueda guardarla en UTF-8. –

+0

Oh, eso es completamente su problema, no hay dudas. Simplemente me resulta más fácil depurar la conversión de texto con un par de StreamReader/StreamWriter (para que pueda ver los archivos de entrada/salida) en lugar de una llamada Encoding.Convert. Eso podría ser solo yo. – Task

Respuesta

32

Necesita obtener el objeto adecuado Encoding. ASCII tiene el mismo nombre: ASCII, lo que significa que solo admite caracteres ASCII de 7 bits. Si lo que quiere hacer es convertir archivos, entonces esto es más fácil que tratar directamente con las matrices de bytes.

using (System.IO.StreamReader reader = new System.IO.StreamReader(fileName, 
             Encoding.GetEncoding("iso-8859-1"))) 
{ 
    using (System.IO.StreamWriter writer = new System.IO.StreamWriter(
              outFileName, Encoding.UTF8)) 
    { 
     writer.Write(reader.ReadToEnd()); 
    } 
} 

Sin embargo, si usted quiere tener las matrices de bytes a sí mismo, es bastante fácil de ver con Encoding.Convert.

byte[] converted = Encoding.Convert(Encoding.GetEncoding("iso-8859-1"), 
    Encoding.UTF8, data); 

Es importante observar aquí, sin embargo, que si se quiere ir por este camino, entonces debería no utilizar un lector de strings basados ​​en la codificación como StreamReader para su archivo de IO. FileStream sería más adecuado, ya que leerá los bytes reales de los archivos.

Con el fin de estudiar a fondo de la cuestión, algo como esto funcionaría:

using (System.IO.FileStream input = new System.IO.FileStream(fileName, 
            System.IO.FileMode.Open, 
            System.IO.FileAccess.Read)) 
{ 
    byte[] buffer = new byte[input.Length]; 

    int readLength = 0; 

    while (readLength < buffer.Length) 
     readLength += input.Read(buffer, readLength, buffer.Length - readLength); 

    byte[] converted = Encoding.Convert(Encoding.GetEncoding("iso-8859-1"), 
         Encoding.UTF8, buffer); 

    using (System.IO.FileStream output = new System.IO.FileStream(outFileName, 
             System.IO.FileMode.Create, 
             System.IO.FileAccess.Write)) 
    { 
     output.Write(converted, 0, converted.Length); 
    } 
} 

En este ejemplo, la variable buffer se llena con los datos reales en el archivo como un byte[], así que no hay conversión es hecho. Encoding.Convert especifica una codificación de origen y de destino, luego almacena los bytes convertidos en la variable llamada ... converted. Esto se escribe en el archivo de salida directamente.

Como dije, la primera opción usando StreamReader y StreamWriter será mucho más simple si esto es todo lo que estás haciendo, pero el último ejemplo debería darte más pistas sobre lo que está sucediendo realmente.

+0

gracias a todos por la ayuda y esp @ Adam por su respuesta completa – Tim

10

Si los archivos son relativamente pequeñas (por ejemplo, ~ 10 megabytes), lo único que necesita dos líneas de código:

string txt = System.IO.File.ReadAllText(inpPath, Encoding.GetEncoding("iso-8859-1")); 
    System.IO.File.WriteAllText(outPath, txt); 
+0

funcionó para mí .. –

+0

Para mí también. – Cheloide

Cuestiones relacionadas