¿Cómo encontrar la encoding de un archivo? DO#

Bueno, necesito averiguar cuál de los archivos que encontré en algún directorio es codificado en UTF8 codificado en ANSI para cambiar la encoding en otra cosa que decida más adelante. Mi problema es … ¿cómo puedo averiguar si un archivo está codificado en UTF8 o ANSI? Ambas codificaciones son realmente posibles en mis archivos.

No existe una manera confiable de hacerlo (ya que el archivo puede ser simplemente binario al azar), sin embargo, el proceso realizado por el software del Bloc de notas de Windows se detalla en el blog de Micheal S Kaplan:

http://www.siao2.com/2007/04/22/2239345.aspx

  1. Verifica los primeros dos bytes; 1. Si hay una BOM de UTF-16 LE, trátela (y cárguela) como un archivo “Unicode”; 2. Si hay una BOM BE de UTF-16, trátela (y cárguela) como un archivo “Unicode (Big Endian)”; 3. Si los primeros dos bytes se parecen al inicio de una lista de materiales UTF-8, luego verifique el siguiente byte y si tenemos una lista de materiales UTF-8, luego trátela (y cárguela) como un archivo “UTF-8”;
  2. Verifique con IsTextUnicode para ver si esa función cree que es BOM-less UTF-16 LE, de ser así, luego trátela (y cárguela) como un archivo “Unicode”;
  3. Verifique si es UTF-8 usando la definición RFC 2279 original de 1998 y si luego la trata (y la carga) como un archivo “UTF-8”;
  4. Suponga un archivo ANSI utilizando la página de códigos del sistema predeterminada de la máquina.

Ahora tenga en cuenta que hay algunos agujeros aquí, como el hecho de que el paso 2 no funciona tan bien con BOM-less UTF-16 BE (incluso puede haber un error aquí, no estoy seguro, si es así, es un error en el Bloc de notas más allá de cualquier error en IsTextUnicode).

http://msdn.microsoft.com/en-us/netframework/aa569610.aspx#Question2

No hay una gran manera de detectar una página de códigos ANSI arbitraria, aunque se han realizado algunos bashs para hacer esto en función de la probabilidad de ciertas secuencias de bytes en el medio del texto. No probamos eso en StreamReader. Algunos formatos de archivo como XML o HTML tienen una forma de especificar el conjunto de caracteres en la primera línea del archivo, de modo que los navegadores web, las bases de datos y las clases como XmlTextReader pueden leer estos archivos correctamente. Pero muchos archivos de texto no tienen este tipo de información incorporada.

Unicode / UTF8 / UnicodeBigEndian se consideran diferentes tipos. ANSI se considera lo mismo que UTF8.

 public class EncodingType { public static System.Text.Encoding GetType(string FILE_NAME) { FileStream fs = new FileStream(FILE_NAME, FileMode.Open, FileAccess.Read); Encoding r = GetType(fs); fs.Close(); return r; } public static System.Text.Encoding GetType(FileStream fs) { byte[] Unicode = new byte[] { 0xFF, 0xFE, 0x41 }; byte[] UnicodeBIG = new byte[] { 0xFE, 0xFF, 0x00 }; byte[] UTF8 = new byte[] { 0xEF, 0xBB, 0xBF }; //with BOM Encoding reVal = Encoding.Default; BinaryReader r = new BinaryReader(fs, System.Text.Encoding.Default); int i; int.TryParse(fs.Length.ToString(), out i); byte[] ss = r.ReadBytes(i); if (IsUTF8Bytes(ss) || (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF)) { reVal = Encoding.UTF8; } else if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00) { reVal = Encoding.BigEndianUnicode; } else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41) { reVal = Encoding.Unicode; } r.Close(); return reVal; } private static bool IsUTF8Bytes(byte[] data) { int charByteCounter = 1; byte curByte; for (int i = 0; i < data.Length; i++) { curByte = data[i]; if (charByteCounter == 1) { if (curByte >= 0x80) { while (((curByte <<= 1) & 0x80) != 0) { charByteCounter++; } if (charByteCounter == 1 || charByteCounter > 6) { return false; } } } else { if ((curByte & 0xC0) != 0x80) { return false; } charByteCounter--; } } if (charByteCounter > 1) { throw new Exception("Error byte format"); } return true; } } 

Vea estos dos artículos del proyecto de código: no es trivial descubrir la encoding de archivos simplemente desde el contenido del archivo:

  • Detectar encoding de ByteOrderMarks (BOM)
  • Detectar encoding para texto entrante y saliente