Necesito para determinar si un archivo de texto el contenido es igual a una de estas codificaciones de texto:

System.Text.Encoding.ASCII
System.Text.Encoding.BigEndianUnicode ' UTF-L 16
System.Text.Encoding.Default ' ANSI
System.Text.Encoding.Unicode ' UTF16
System.Text.Encoding.UTF32
System.Text.Encoding.UTF7
System.Text.Encoding.UTF8

No sé cómo leer el byte de marcas de los archivos, he visto fragmentos de hacer esto, pero sólo se puede determinar si un archivo ASCII o Unicode, por lo tanto necesito algo más universal.

  • Usted no puede fiable de hacerlo.
  • stackoverflow.com/questions/3825390/…
  • por favor, consulte los comentarios en la respuesta, lo he probado también, pero devuelve la codificación de VS, no codificación del archivo. devuelve «UTF8» cuando el archivo está en codificación ANSI.
  • Hilgarth por favor puedes decir ¿por qué crees eso?, Yo no soy un experto pero creo que si que no se podía hacer de forma fiable, a continuación, el «notepad.exe» no se puede de forma fiable de saber qué tipo de codificación que se utiliza un archivo en el bloc de notas pero siempre sabe y siempre muestra la exacta codificación de esos cuando usted presione el botón «guardar».
  • ups, lo siento, a continuación,
  • Hay ciertos indicadores a partir de la cual puede inferir, pero usted puede obtener falsos positivos con este enfoque. Por ejemplo, UTF-8 puede ser utilizado sin una lista de materiales y, como tal, se ve muy similar a un archivo ASCII. Ah, y no es el cifrado de los involucrados. Es la codificación de
  • Hilgarth sé que el «cifrado» la palabra era un GoogleTranslate fallar traduction, gracias por comentar
  • Que necesito para trabajar con archivos de texto en una aplicación, que es lo mejor que puedo hacer? dígale al usuario especificar la codificación de texto por sí mismo, cuando la apertura de un archivo?
  • Eres tú el único interesado en saber cómo leer la lista de materiales, o estás interesado en la determinación de la codificación, incluso cuando un MOB no está presente?
  • Doggart yo no sabía archivos podrían contener BOM o también puede que no los contiene, así que no sé realmente lo que necesito, no sé si más utilizados archivo de texto codificaciones tienen marca de orden de bytes o no, sólo necesito saber la codificación del archivo de texto, pero esto parece muy, muy difícil…
  • No hay ninguna forma genérica para hacer esto? ¿cómo puede hacerlo Notepadd++ con muy agradable precisión?
  • No sé ni por qué un moderador marcado esta respuesta, mientras yo estoy pidiendo VBNET solución y la respuesta es para C# y también se supone que la solución no funciona…

1 Comentario

  1. 56

    El primer paso es cargar el archivo como una matriz de bytes en lugar de como una cadena. Las cadenas se almacenan siempre en la memoria con la codificación UTF-16, así que una vez que se carga en una cadena, en la codificación original se pierde. He aquí un ejemplo simple de una manera de cargar un archivo en una matriz de bytes:

    Dim data() As Byte = File.ReadAllBytes("test.txt")

    Determinar automáticamente la codificación correcta para un determinado conjunto de bytes es muy difícil. A veces, para ser útil, el autor de los datos se inserte algo que se llama un BOM (Byte Order Mark) en el comienzo de los datos. Si una lista de materiales está presente, que hace que la detección de la codificación indolora, ya que cada uno de codificación utiliza diferentes MATERIALES.

    La manera más fácil de detectar automáticamente la codificación de la lista de materiales es dejar que el StreamReader hacer por usted. En el constructor de la StreamReader, usted puede pasar True para la detectEncodingFromByteOrderMarks argumento. A continuación, puede obtener la codificación de la secuencia de acceso a su CurrentEncoding de la propiedad. Sin embargo, la CurrentEncoding propiedad no funcionan hasta después de la StreamReader ha leído la lista de materiales. Así que primero hay que leer más allá de la lista de materiales antes de que usted puede conseguir la codificación, por ejemplo:

    Public Function GetFileEncoding(filePath As String) As Encoding
        Using sr As New StreamReader(filePath, True)
            sr.Read()
            Return sr.CurrentEncoding
        End Using
    End Function

    Sin embargo, el problema de este enfoque es que la MSDN parece implicar que el StreamReader sólo puede detectar ciertos tipos de codificaciones:

    La detectEncodingFromByteOrderMarks parámetro detecta la codificación mirando a los tres primeros bytes de la secuencia. Reconoce automáticamente la codificación UTF-8, «little-endian» Unicode, y big-endian de texto Unicode si el archivo se inicia con la correspondiente marca de orden de byte. Ver la Codificación.GetPreamble método para obtener más información.

    También, si el StreamReader es incapaz de determinar la codificación de la lista de materiales, o si la lista de materiales no está allí, no sólo por defecto para la codificación UTF-8, sin darle ninguna indicación de que ha fallado. Si usted necesita un control más granular que eso, usted puede muy fácil de leer la lista de materiales y la interpretan a sí mismo. Todo lo que tienes que hacer es comparar los primeros bytes de la matriz de bytes con algunos conocidos, espera BOM para ver si coinciden. Aquí está una lista de algunas común BOM:

    • UTF-8: EF BB BF
    • UTF-16 orden de bytes big endian: FE FF
    • UTF-16 little endian el orden de los bytes: FF FE
    • UTF-32 orden de bytes big endian: 00 00 FE FF
    • UTF-32 «little endian» el orden de los bytes: FF FE 00 00

    Así, por ejemplo, a ver si UTF-16 (little endian) lista de materiales que existe en el comienzo de la matriz de bytes, usted podría simplemente hacer algo como esto:

    If (data(0) = &HFF) And (data(1) = &HFE) Then
        ' Data starts with UTF-16 (little endian) BOM
    End If

    Muy bien, la Encoding clase .NET contiene un método llamado GetPreamble que devuelve la lista de materiales utilizados por la codificación, de modo que no tenga que acordarse de lo que son. Así, para comprobar si una matriz de bytes que comienza con la lista de materiales para Unicode (UTF-16 little-endian), se podría hacer esto:

    Function IsUtf16LittleEndian(data() as Byte) As Boolean
        Dim bom() As Byte = Encoding.Unicode.GetPreamble()
        If (data(0) = bom(0)) And (data(1) = bom(1) Then
            Return True
        Else
            Return False
        End If
    End Function

    Por supuesto, la función anterior supone que los datos están a menos de dos bytes de longitud y la lista de materiales es exactamente dos bytes. Así, mientras que ilustra cómo lo hacen tan claramente como sea posible, no es la forma más segura de hacerlo. Para hacer que sea tolerante con las diferentes matriz de longitudes, especialmente desde la lista de materiales longitudes de los mismos pueden variar de una codificación a la siguiente, que sería más seguro para hacer algo como esto:

    Function IsUtf16LittleEndian(data() as Byte) As Boolean
        Dim bom() As Byte = Encoding.Unicode.GetPreamble()
        Return data.Zip(bom, Function(x, y) x = y).All(Function(x) x)
    End Function

    Así, el problema se convierte entonces, ¿cómo conseguir una lista de todas las codificaciones? Pues da la casualidad de que el .NET Encoding clase también proporciona un método compartido (estático) llamado GetEncodings que devuelve una lista de todos los dispositivos de codificación de los objetos. Por lo tanto, usted podría crear un método que recorre la totalidad de la codificación de los objetos, se presenta la lista de materiales de cada uno y la compara con la matriz de bytes hasta encontrar uno que coincida con. Por ejemplo:

    Public Function DetectEncodingFromBom(data() As Byte) As Encoding
        Return Encoding.GetEncodings().
            Select(Function(info) info.GetEncoding()).
            FirstOrDefault(Function(enc) DataStartsWithBom(data, enc))
    End Function
    
    Private Function DataStartsWithBom(data() As Byte, enc As Encoding) As Boolean
        Dim bom() As Byte = enc.GetPreamble()
        If bom.Length <> 0 Then
            Return data.
                Zip(bom, Function(x, y) x = y).
                All(Function(x) x)
        Else
            Return False
        End If
    End Function

    Una vez finalizada la función, entonces usted podría detectar la codificación de un archivo como este:

    Dim data() As Byte = File.ReadAllBytes("test.txt")
    Dim detectedEncoding As Encoding = DetectEncodingFromBom(data)
    If detectedEncoding Is Nothing Then
        Console.WriteLine("Unable to detect encoding")
    Else
        Console.WriteLine(detectedEncoding.EncodingName)
    End If

    Sin embargo, el problema sigue siendo, ¿cómo se puede detectar automáticamente la codificación correcta cuando no hay ninguna lista de materiales? Técnicamente se recomienda que usted no pone una lista de materiales en el comienzo de sus datos cuando se utiliza la codificación UTF-8, y no hay ninguna lista de materiales definidos para cualquiera de las páginas de códigos ANSI. Así que es ciertamente fuera de la esfera de la posibilidad de que un archivo de texto no puede tener una lista de materiales. Si todos los archivos que son en inglés, es probablemente seguro asumir que si no hay lista de materiales está presente, entonces UTF-8 será suficiente. Sin embargo, si alguno de los archivos ocurrir usar otra cosa, sin lista de materiales, luego de que no funciona.

    Como usted bien observado, existen aplicaciones que todavía detectar automáticamente la codificación incluso cuando no hay ninguna lista de materiales está presente, pero lo hacen a través de la heurística (es decir, suposiciones) y, a veces, no son exactas. Básicamente, se carga los datos de utilización de cada uno de codificación y, a continuación, ver si los datos se «ve» inteligible. Esta página ofrece algunos interesantes puntos de vista sobre los problemas dentro del Bloc de notas auto-algoritmo de detección. Esta página se muestra cómo se puede aprovechar la COM-automático basado en el algoritmo de detección que se utiliza Internet Explorer (en C#). Aquí está una lista de algunos de los C# bibliotecas que las personas han escrito que intenta detectar automáticamente la codificación de una matriz de bytes, que puede encontrar útiles:

    Aunque esta pregunta fue para C#, usted también puede encontrar las respuestas a lo útil.

    • Si podría establecer en un botón de favoritos respuestas, este sería uno de ellos, gracias!
    • Gracias! He añadido información acerca de cómo hacerlo con el StreamReader que es un punto importante a incluir. Creo que la razón por la que estaba fallando para el pueblo, en ese otro C# respuesta que fue marcado como el duplicado, es porque no hacer un Read sobre el arroyo primero antes de llegar a la codificación. Hasta que se lee más allá de la lista de materiales, simplemente devolverá el valor predeterminado de codificación UTF-8.
    • El StreamReader método devuelve UTF8 para los archivos ANSI, todavía me preffering el primer método que he escrito porque detecta agradable UTF8 archivos y también si cualquier codificación es detectada, entonces puedo devolver un «posiblemente Más de la codificación de la» casualidad como la codificación ANSI, y que funcionó muy agradable para mí, para detectar los archivos ANSI y UTF archivo, pero creo que el mismo no puede ser hecho con el sr método en pocas líneas, gracias de nuevo!
    • Correcto, ya que ANSI los archivos codificados nunca tiene una lista de materiales, el StreamReader va a suponer siempre que el defecto UTF-8. Estoy todavía no entiendo por qué todo el mundo votaron para cerrar este como un duplicado. La otra respuesta es incorrecta y en C#. Extraño. He votado a favor para volver a ella. Vamos a ver si se va a ninguna parte. En cualquier caso, me alegro de que podría ayudar.
    • Pendientes de respuesta! Gracias realmente me salvó el día!

Dejar respuesta

Please enter your comment!
Please enter your name here