Con referencia al siguiente hilo: Aplicación Java: no se puede leer el archivo codificado iso-8859-1 correctamente
¿Cuál es la mejor manera de determinar mediante programación la codificación correcta del juego de caracteres de un flujo de entrada / archivo?
He intentado usar lo siguiente:
File in = new File(args[0]);
InputStreamReader r = new InputStreamReader(new FileInputStream(in));
System.out.println(r.getEncoding());
Pero en un archivo que sé que está codificado con ISO8859_1, el código anterior produce ASCII, que no es correcto, y no me permite reproducir correctamente el contenido del archivo en la consola.
Reader.getEncoding
devuelve la codificación que el lector fue configurado para usar, que en su caso es la codificación predeterminada.Respuestas:
He usado esta biblioteca, similar a jchardet para detectar la codificación en Java: http://code.google.com/p/juniversalchardet/
fuente
No puede determinar la codificación de una secuencia de bytes arbitraria. Esta es la naturaleza de las codificaciones. Una codificación significa un mapeo entre un valor de byte y su representación. Entonces cada codificación "podría" ser la correcta.
El método getEncoding () devolverá la codificación que se configuró (lea el JavaDoc ) para la secuencia. No adivinará la codificación por usted.
Algunas transmisiones le indican qué codificación se utilizó para crearlas: XML, HTML. Pero no una secuencia de bytes arbitraria.
De todos modos, podrías intentar adivinar una codificación por tu cuenta si es necesario. Cada idioma tiene una frecuencia común para cada char. En inglés, el carácter aparece muy a menudo, pero ê aparecerá muy muy raramente. En una secuencia ISO-8859-1 generalmente no hay caracteres 0x00. Pero una transmisión UTF-16 tiene muchos de ellos.
O: podrías preguntarle al usuario. Ya he visto aplicaciones que le presentan un fragmento del archivo en diferentes codificaciones y le piden que seleccione la "correcta".
fuente
mira esto: http://site.icu-project.org/ (icu4j) tienen bibliotecas para detectar charset de IOStream, podría ser simple como este:
fuente
Aquí están mis favoritos:
TikaEncodingDetector
Dependencia:
Muestra:
GuessEncoding
Dependencia:
Muestra:
fuente
CharsetDectector
.Ciertamente, puede validar el archivo para un conjunto de caracteres en particular decodificándolo con un
CharsetDecoder
y vigilando los errores de "entrada mal formada" o "caracteres no asignables". Por supuesto, esto solo te dice si un juego de caracteres está mal; no te dice si es correcto. Para eso, necesita una base de comparación para evaluar los resultados decodificados, por ejemplo, ¿sabe de antemano si los caracteres están restringidos a algún subconjunto o si el texto se adhiere a algún formato estricto? La conclusión es que la detección de juegos de caracteres es una conjetura sin ninguna garantía.fuente
¿Qué biblioteca usar?
Al escribir estas líneas, son tres bibliotecas que emergen:
No incluyo Apache Any23 porque usa ICU4j 3.4 debajo del capó.
¿Cómo saber cuál ha detectado el juego de caracteres correcto (o lo más cerca posible)?
Es imposible certificar el conjunto de caracteres detectado por cada biblioteca anterior. Sin embargo, es posible preguntarles por turno y calificar la respuesta devuelta.
¿Cómo calificar la respuesta devuelta?
A cada respuesta se le puede asignar un punto. Cuantos más puntos tenga una respuesta, más confianza tendrá el juego de caracteres detectado. Este es un método de puntuación simple. Puedes elaborar otros.
¿Hay algún código de muestra?
Aquí hay un fragmento completo que implementa la estrategia descrita en las líneas anteriores.
Mejoras: el
guessEncoding
método lee el flujo de entrada por completo. Para grandes flujos de entrada esto puede ser una preocupación. Todas estas bibliotecas leerían todo el flujo de entrada. Esto implicaría un gran consumo de tiempo para detectar el juego de caracteres.Es posible limitar la carga de datos inicial a unos pocos bytes y realizar la detección de juego de caracteres solo en esos pocos bytes.
fuente
Las bibliotecas anteriores son simples detectores de BOM que, por supuesto, solo funcionan si hay una BOM al comienzo del archivo. Echa un vistazo a http://jchardet.sourceforge.net/ que escanea el texto
fuente
Hasta donde sé, no hay una biblioteca general en este contexto que sea adecuada para todo tipo de problemas. Por lo tanto, para cada problema, debe probar las bibliotecas existentes y seleccionar la mejor que satisfaga las restricciones de su problema, pero a menudo ninguna de ellas es apropiada. En estos casos, puede escribir su propio detector de codificación. Como he escrito ...
He escrito una herramienta meta java para detectar la codificación de juegos de caracteres de páginas web HTML, utilizando IBM ICU4j y Mozilla JCharDet como componentes integrados. Aquí puede encontrar mi herramienta, lea la sección README antes que nada. Además, puede encontrar algunos conceptos básicos de este problema en mi artículo y en sus referencias.
A continuación proporcioné algunos comentarios útiles que he experimentado en mi trabajo:
fuente
Encontré una buena biblioteca de terceros que puede detectar la codificación real: http://glaforge.free.fr/wiki/index.php?wiki=GuessEncoding
No lo probé extensamente, pero parece funcionar.
fuente
Si usa ICU4J ( http://icu-project.org/apiref/icu4j/ )
Aquí está mi código:
Recuerda poner todo el try-catch que lo necesites.
Espero que esto funcione para ti.
fuente
Si no conoce la codificación de sus datos, no es tan fácil de determinar, pero podría intentar usar una biblioteca para adivinarlo . Además, hay una pregunta similar .
fuente
Para los archivos ISO8859_1, no existe una manera fácil de distinguirlos de ASCII. Sin embargo, para archivos Unicode, generalmente se puede detectar esto en función de los primeros bytes del archivo.
Los archivos UTF-8 y UTF-16 incluyen una marca de orden de bytes (BOM) al comienzo del archivo. La lista de materiales es un espacio sin ruptura de ancho cero.
Desafortunadamente, por razones históricas, Java no detecta esto automáticamente. Programas como el Bloc de notas verificará la lista de materiales y utilizará la codificación adecuada. Usando unix o Cygwin, puede verificar la lista de materiales con el comando de archivo. Por ejemplo:
Para Java, le sugiero que consulte este código, que detectará los formatos de archivo comunes y seleccionará la codificación correcta: cómo leer un archivo y especificar automáticamente la codificación correcta
fuente
Una alternativa a TikaEncodingDetector es usar Tika AutoDetectReader .
fuente
En Java simple:
Este enfoque probará las codificaciones una por una hasta que uno funcione o nos quedemos sin ellas. (Por cierto, mi lista de codificaciones tiene solo esos elementos porque son las implementaciones de conjuntos de caracteres requeridas en cada plataforma Java, https://docs.oracle.com/javase/9/docs/api/java/nio/charset/Charset.html )
fuente
¿Puedes elegir el conjunto de caracteres apropiado en el Constructor ?
fuente