para - Juego de caracteres Java y Windows
java offline (5)
Tengo un programa Java que ejecuta msinfo32.exe (información del sistema) en un proceso externo y luego lee el contenido del archivo producido por msinfo32.exe. Cuando el programa Java carga el contenido del archivo en una Cadena, los caracteres de Cadena son ilegibles. Para que la Cadena sea legible, tengo que crear la Cadena usando Cadena (byte [] bytes, Cadena de caracteresName) y establecer el nombre de conjunto de caracteres en UTF-16. Sin embargo, cuando se ejecuta en una instancia de Windows2003, solo UTF-16LE (little endian) da como resultado una cadena imprimible.
¿Cómo puedo saber de antemano qué codificación de caracteres usar?
Además, cualquier información de fondo sobre este tema sería apreciada.
Algunas aplicaciones de Microsoft utilizan una marca de orden de bytes para indicar los archivos Unicode y su endianness. Puedo ver en mi máquina con Windows XP que el archivo .NFO exportado comienza con 0xFFFE, por lo que es little-endian.
FF FE 3C 00 3F 00 78 00 6D 00 6C 00 20 00 76 00 __<_?_x_m_l_ _v_
65 00 72 00 73 00 69 00 6F 00 6E 00 3D 00 22 00 e_r_s_i_o_n_=_"_
31 00 2E 00 30 00 22 00 3F 00 3E 00 0D 00 0A 00 1_._0_"_?_>_____
3C 00 4D 00 73 00 49 00 6E 00 66 00 6F 00 3E 00 <_M_s_I_n_f_o_>_
0D 00 0A 00 3C 00 4D 00 65 00 74 00 61 00 64 00 ____<_M_e_t_a_d_
Además, le recomiendo que cambie a usar implementaciones de Reader en lugar del constructor de cadenas para decodificar archivos; esto ayuda a evitar problemas donde lee medio carácter porque está truncado porque está situado al final de una matriz de bytes.
La forma en que se supone que debe funcionar es que, si alguien le da un archivo y dice que es UTF-16, esperan que examine los primeros dos bytes (la lista de materiales) para averiguar si es big-endian o little-endian. Pero si te dicen que la codificación es UTF-16LE , significa que no hay lista de materiales; no lo necesitas porque ya te han dicho que la orden de bytes es little-endian. Java sigue estas reglas con precisión, lo cual es una verdadera molestia porque nadie más lo hace.
La codificación de caracteres nativos de los sistemas operativos modernos de Windows es UTF-16, little-endian. Desafortunadamente, los programas individuales no parecen ser consistentes cuando se trata de marcas de orden de bytes. Y no puedes usar UTF-16LE todo el tiempo porque, si la lista de materiales está allí, se pasará como un carácter basura. La única forma de saber de antemano si se debe usar UTF-16 o UTF-16LE es examinar los primeros dos bytes, como describió McDowell.
No se puede saber realmente qué codificación de caracteres se ha utilizado (a menos que haya creado la herramienta que creó el resultado que está procesando). Puede tratar de detectar una lista de codificaciones predefinidas y elegir una que no dé lugar a ningún error de descodificación, sino que depende de la entrada que pueda coincidir con muchas codificaciones diferentes.
Podría intentar usar una biblioteca para adivinar la codificación, por ejemplo, una vez utilicé esta solución .
Si no conoce de antemano la codificación de caracteres y esto es diferente entre varias plataformas, entonces debe analizar de algún modo la matriz de bytes para intentar adivinarla. Hay algunos algoritmos de detección disponibles, pero puede ser una exageración para su aplicación.
¿Puede modificar su aplicación para producir una salida conocida? No es necesario que sea una línea completa, solo los primeros personajes lo harán. Si es así, entonces podría comparar la matriz de bytes producidos con la esperada en varias codificaciones y hacer la detección. Las matrices de bytes de UTF8, UTF-16 big y little endian serán eventos diferentes para strings simples.