detectar-a-bajo-nivel-si-un-fichero-es-utf-8-desde-java

Detectar a bajo nivel si un fichero es UTF-8 desde Java

Aunque inicialmente parece una tarea muy sencilla, los que hayan tenido que detectar si un fichero es UTF-8 se habrán dado cuenta que el tema no es ta obvio como parece.

Primero una introducción teórica

Los ficheros se almacenan como arrays de bytes que posteriormente son asociados a caracteres, para hacer esta asociación se utilizan diferentes codificaciones ( ASCII, ISO-8859-1,UTF-8,etc).

Para poder establecer una relación entre su código y cualquier carácter utilizado por cualquier lenguaje del mundo se creo Unicode, que no es mas que una gigantesca asociación código numérico-grafía para permitir su representación informática.

Dentro de este contexto, UTF-8 no es mas que una forma de codificar un texto Unicode para permitir su serialización en ficheros o flujos de datos.

Ya que Unicode intenta asociar códigos a todos los caracteres esenciales, necesitamos mas de un byte para codificarlos, por lo que UTF-8 recurre a una estructura variable de entre 1 a 4 bytes para codificar los diferentes caracteres.

Este tamaño variable es el motivo por el que en ocasiones los ficheros guardados con un formato se ven con caracteres extraños al recuperarlos utilizando la codificación incorrecta.

Aproximación al Algorítmo

El proceso es muy sencillo, basta leer el fichero byte a byte e ir comprobando que todos los bytes cumplen con lo especificado en el estandar UTF-8.

  • Si el byte leído es menor que 0111 1111 (0x7F) es un byte válido. En este caso el byte representa un caracter UTF-8 (de 1 byte).
  • Si el byte leído coincide con la mascara 110xxxxx, compruebo que el siguiente byte cumple con la mascara 10xxxxxx. En este caso los dos bytes leídos forman el carácter UTF-8.
  • De forma similar se pueden detectar si son caracteres de 3 o 4 bytes.

Si en algún momento del procesamiento del fichero, alguna de las condiciones no se cumple, el fichero no es UTF-8, en otro caso tiene una codificación compatible con UTF-8.

Aunque seguro que existen implementaciones mucho mas eficientes en Java, después de algunas búsquedas en Internet no encontré nada, por lo que me lance a programar mi propio validador.

Recorte de código para detectar si un fichero está codificado en UTF-8