2009-08-20 9 views
10

(Disculpe si esto es un engaño)Encoding.Default no es lo mismo que ninguna codificación en File.ReadAllText?

He pasado mucho tiempo tratando de leer un archivo de texto correctamente.

Después de haber comenzado con File.ReadAllText(path) y conseguir caracteres atornillados-para arriba, he intentado varias variantes de File.ReadAlltext(path, Encoding) después de lo cual se atascaron tratando de analizar mis archivos de entrada para averiguar qué era el problema de bytes, etc.

En la desesperación ¡Intenté File.ReadAllText(path, Encoding.Default), que funcionó!

Ahora me cuesta entender por qué el valor predeterminado es aparentemente solo el valor predeterminado si lo especifica.

(Mi cadena de prueba corte hacia abajo era +4433ç, lo guardé en el bloc de notas como ANSI - aunque con ajustes regionales franceses suizos ...)

+2

Tenga en cuenta que Encoding.Default no debe considerarse como la codificación "por defecto" - es la codificación (no Unicode!) Para el sistema por defecto de la página de códigos * *. –

Respuesta

10

Encoding.Default es la página de códigos ANSI del sistema.

Lo que hace File.ReadAllText si no se especifica una codificación es la siguiente:

  • En primer lugar se comprueba si hay una marca de orden de bytes (UTF-8, UTF-16 o UTF-32). Si lo hay, usa la codificación especificada en la marca de orden de bytes.
  • De lo contrario, usa UTF-8.

Así que la única manera de obtener la página de códigos ANSI del sistema es especificar explícitamente Encoding.Default.

+0

File.ReadAllText no comprueba la marca de orden de bytes. Siempre usará UTF-8, si no especifica la codificación. Esto es confirmado tanto por Reflector como por la fuente de referencia .NET. –

+4

Jivko, no creo que tu comentario sea correcto. ReadAllText sin una codificación llama a ReadAllText (ruta, Encoding.UTF8), pero la secuencia interna utilizada por ReadAllText leerá la lista de materiales si está presente y reemplazará la codificación con la codificación detectada. Esto se debe a que detectEncodingFromByteOrderMarks está establecido en true en el constructor de StreamReader. –

2

De MSDN, acerca de la ReadAllText cadena (string path) Sobrecarga:

Este método intenta detectar automáticamente la codificación de un archivo

Así que no, no es lo mismo que usar la codificación predeterminada

3

UTF8 es el valor predeterminado real y solo se usa cuando la detección automática no encuentra ninguna codificación. Entonces, la lista de materiales es más importante. Ver detalles más abajo:

ReadAllText(string path) - MSDN: "Este método intenta detectar automáticamente la codificación"

ReadAllText(string path, Encoding encoding) - MSDN: "Este método intenta detectar automáticamente la codificación"

Desde herramienta de reflector: ReadAllText(path) es lo mismo que ReadAllText(path, Encoding.UTF8), porque ReadAllText(path) solo llama al ReadAllText(path, Encoding.UTF8). Ambos métodos crean StreamReader de esta manera:

public StreamReader(string path, Encoding encoding) : this(path, encoding, true, 0x400) 
{ 
} 

Esto significa que se crea StreamReader(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize) con detectEncodingFromByteOrderMarks establecidas en true. Esto significa que si la Marca de Orden de Byte (BOM) está presente usará la codificación de la lista de materiales, si la lista de materiales no está presente, utilizará la codificación proporcionada. Si la lista de materiales no está presente y no se proporciona la codificación, usará UTF8. Entonces, el UTF8 es el valor predeterminado real en este caso, pero recuerde que la lista de materiales es más importante que la codificación sugerida.

// bom.txt is the file with BOM present. nobom.txt - witout BOM 
File.ReadAllText("bom.txt");      // use BOM 
File.ReadAllText("bom.txt", Encoding.UTF8);  // use BOM 
File.ReadAllText("bom.txt", Encoding.Default); // use BOM 
File.ReadAllText("nobom.txt");     // use UTF-8 
File.ReadAllText("nobom.txt", Encoding.UTF8); // use UTF-8 
File.ReadAllText("nobom.txt", Encoding.Default); // use system's ANSI codepage 
+0

¿Sabes si hay una manera de anular la lista de materiales para que la opción Encoding.whatever se convierta en la prioridad? –

+0

@DanW, puede intentar usar 'new StreamReader (" brokenFile.txt ", Encoding.whatever, false)'. Pero en este caso, probablemente tratará la lista de materiales como texto, de modo que al principio obtendrá caracteres extraños. Asegúrese de lo que está haciendo porque, cuando se establece la lista de materiales, entonces generalmente se configura correctamente. – CoperNick

Cuestiones relacionadas