FreeToGenerate.com

Un archivo .properties no tiene codificación propia: la decide el cargador, y los dos cargadores no coinciden. No se sube nada.

Prueba uno:

Lo escribes aquí como texto y la página lo codifica en UTF-8, que es lo que guarda cualquier editor actual. Las dos columnas de abajo muestran qué leería cada uno de los dos cargadores de Java a partir de esos bytes.

Qué lee cada cargador

Los dos cargadores discrepan. El archivo está guardado en UTF-8 y load(InputStream) lee un carácter por byte, así que todo lo que no sea ASCII llega convertido en dos o tres caracteres en lugar de uno.

Claveload(InputStream), ISO 8859-1load(Reader), UTF-8
greetingdiscrepancafécafé
farewelldiscrepanadiósadiós
ascii.onlythis line is fine either waythis line is fine either way

Los mismos bytes, descodificados de dos maneras. Las filas marcadas son aquellas en las que ambos discrepan: ahí tu programa verá un valor distinto según cómo se haya abierto el archivo.

Conviene saber

Nada que señalar.

La forma que no depende del cargador

Todo lo que no es ASCII escrito como escape, de manera que ambos cargadores leen exactamente lo mismo. Es lo que produce store(OutputStream) y la única forma que no se estropea porque un editor cambie la codificación del archivo.

Resumen

Entradas
3
Claves en las que discrepan
2

Todo funciona en tu navegador. Nada de lo que pegues se sube a ningún sitio.

También disponible en: English · Português · Français · العربية

Archivo .properties de Java: acentos, escapes y codificación

Pega un archivo .properties y compara lo que lee cada cargador de Java a partir de los mismos bytes, junto con la forma escapada que los pone de acuerdo.

Qué es un archivo .properties

El archivo .properties es el formato de configuración más antiguo y más simple de Java: una clave y un valor por línea, separados por un signo igual, y una almohadilla para los comentarios. Está en la biblioteca estándar desde el principio, sigue siendo el formato de la mayoría de los paquetes de traducción y es lo bastante sencillo como para que cualquiera lo edite con el programa que tenga abierto.

Esa simplicidad esconde algo. Un archivo .properties no tiene codificación propia. Nada dentro del archivo indica cuál es, no hay cabecera ni marca de orden de bytes, y la respuesta depende por entero del método que lo abrió. Si se lee con el método de flujo, cada byte se convierte en un carácter, es decir, ISO 8859-1. Si se lee con el método de lector, la codificación es la que se le diera a ese lector. Y la variante XML del mismo formato usa UTF-8 por omisión. Un solo formato, tres respuestas.

Por eso el archivo que se ve bien en tu editor no es necesariamente el archivo que lee tu programa. Esta página muestra ambas lecturas de los mismos bytes, señala los valores en los que difieren y te da la forma escapada que los dos cargadores leen igual.

Cómo se usa

  1. Pega el archivo. Se codifica en UTF-8, que es lo que guarda un editor actual. Los botones de ejemplo cubren texto con tildes, ese mismo texto ya escapado, las reglas de separadores y comentarios, una ruta de Windows y una línea continuada.
  2. Compara las dos columnas. Una es lo que lee el cargador de flujo y otra lo que lee un lector UTF-8, ambas a partir de los mismos bytes. Una fila marcada es un valor que tu programa verá distinto según cómo se abriera el archivo.
  3. Quédate con la forma escapada. Todo lo que no es ASCII escrito como escape. Esa versión no se rompe porque un editor cambie la codificación del archivo, y es lo que escribe Java cuando guarda un .properties.

Por qué el mismo archivo se lee de dos maneras

La documentación lo dice sin rodeos: los métodos de flujo funcionan igual que los de lector salvo que el flujo está codificado en ISO 8859-1 y cada byte es un carácter Latin-1. La implementación es todavía más directa: un byte se convierte en carácter enmascarando sus ocho bits bajos, sin descodificador de por medio.

Así, un archivo guardado en UTF-8 y leído con el método de flujo da un carácter por byte. Una e con tilde ocupa dos bytes en UTF-8, y esos dos bytes se convierten en dos caracteres: por eso café llega como café. El valor no se corrompe por el camino ni nadie avisa; simplemente se descodifica con una regla en la que no estaba pensando quien guardó el archivo.

Hay aquí una distinción que conviene precisar, porque es fácil entenderla al revés. Una letra latina con tilde sí se puede representar en ISO 8859-1: la e acentuada es un solo byte allí. El problema no es que el carácter no se pueda escribir, sino que el archivo se escribió con una codificación distinta de la que se está usando para leerlo. Un carácter por encima de U+00FF es otro caso: ese no se puede escribir en ISO 8859-1 de ninguna manera, y hay que escaparlo para que el cargador de flujo lo vea, se guarde el archivo como se guarde.

El escape que resuelve ambos casos es una barra invertida, la letra u y cuatro dígitos hexadecimales. Cuatro exactamente, y una sola u: así lo dice la documentación, y la implementación de referencia lanza una excepción en lugar de adivinar si encuentra otra cosa. El detalle tiene su gracia, porque el propio lenguaje Java admite cualquier número de letras u en un escape dentro del código fuente. La misma sintaxis, dos reglas distintas, en una sola plataforma.

Las reglas de escape que se comen tus datos

Detrás de una barra invertida solo significan algo cuatro letras: t, r, n y f, para tabulador, retorno de carro, salto de línea y avance de página. Cualquier otro carácter tras la barra es él mismo, y la barra desaparece. Es deliberado, porque así se pone un dos puntos o un igual literal dentro de una clave, pero convierte las rutas de Windows en una trampa.

Escribe una ruta como C, dos puntos, barra invertida, Users, barra invertida, temp, y el resultado es peor que perder los separadores. La primera barra se esfuma antes de la U, y la segunda va seguida de una t, así que se convierte en un tabulador. Lo que recibe tu programa es C, dos puntos, Users, un tabulador invisible y luego emp. Duplicar cada barra invertida es la solución, y explica por qué los archivos .properties llenos de rutas de Windows tienen ese aspecto tan raro.

Las reglas de línea guardan sus propias sorpresas. Una clave termina en el primer igual, dos puntos, espacio, tabulador o avance de página, lo que llegue antes, de modo que una línea que diga clave valor sin ningún signo de puntuación es una entrada perfectamente válida. Los espacios iniciales se eliminan de todas las líneas, tanto la almohadilla como el signo de exclamación abren un comentario, y una línea terminada en barra invertida continúa en la siguiente, a la que también se le quitan los espacios iniciales. Esa última regla es la que permite partir un mensaje largo e indentarlo sin que la indentación acabe formando parte del valor.

Lo que esta herramienta no hace

No decide qué contiene realmente tu archivo en disco. Aquí estás escribiendo texto, y la página lo codifica en UTF-8 porque es lo que guardan los editores de hoy. Si tu archivo está guardado de verdad en ISO 8859-1, entonces el cargador de flujo lo lee bien y es al lector al que hay que decírselo: la misma comparación, al revés.

Se queda en el formato. Si un valor es una URL de base de datos sensata, si una clave pertenece a este paquete, si el mecanismo de resource bundles llegará siquiera a encontrar el archivo: nada de eso se ve en los bytes ni se comprueba aquí. Y si lo que tienes es texto que ya llegó estropeado, la herramienta de reparación de mojibake de este sitio es la página adecuada; esta trata de producir un archivo que no pueda estropearse.

El comportamiento descrito es el de Java. Otros lenguajes leen el mismo formato con sus propias reglas y varios dan por hecho UTF-8, que es precisamente la razón de que un archivo que funciona en una cadena de herramientas se rompa en otra. La forma escapada es el terreno común: es ASCII puro, así que todos los lectores coinciden en ella.

¿Por qué es gratis?

Codificar una cadena y volver a leerla de dos maneras es aritmética que tu navegador hace al instante. No hay servidor de por medio, así que no hay nada que medir ni ninguna cuenta que crear.

No se sube nada. El archivo que pegas se queda en esta pestaña.