convert bom java utf-8 byte-order-mark

convert - Cómo eliminar BOM de un archivo XML en Java



utf 8 sin bom java (1)

Tener una herramienta que se rompe debido a un BOM en un archivo UTF-8 es algo muy común en mi experiencia. No sé por qué hay tantos votos a la baja (pero luego me da la oportunidad de tratar de obtener suficiente voto para ganar una insignia especial de SO)

Más en serio: una lista de materiales UTF-8 normalmente no tiene mucho sentido, pero es totalmente válida (aunque desalentada) según las especificaciones. Ahora el problema es que muchas personas no saben que una lista de materiales es válida en UTF-8 y, por lo tanto, escribieron herramientas / API dañadas que no procesan correctamente estos archivos.

Ahora puede tener dos problemas diferentes: puede querer procesar el archivo de Java o necesita usar Java para crear / reparar archivos que otras herramientas (rotas) necesitan programáticamente.

He tenido el caso en un concierto de consultoría en el que el servicio de asistencia continuaría recibiendo mensajes de usuarios que tenían problemas con algún editor de texto que desordenaría los archivos UTF-8 perfectamente válidos producidos por Java. Así que tuve que solucionar ese problema asegurándome de eliminar la lista de materiales de cada archivo UTF-8 con el que estábamos trabajando.

Si desea eliminar una lista de materiales de un archivo, puede crear un nuevo archivo y omitir los primeros tres bytes. Por ejemplo:

... $ file /tmp/src.txt /tmp/src.txt: UTF-8 Unicode (with BOM) English text ... $ ls -l /tmp/src.txt -rw-rw-r-- 1 tact tact 1733 2012-03-16 14:29 /tmp/src.txt ... $ hexdump -C /tmp/src.txt | head -n 1 00000000 ef bb bf 50 6f 6b 65 ...

Como puede ver, el archivo comienza con "ef bb bf", esta es la lista de materiales UTF-8 (completamente válida).

Aquí hay un método que toma un archivo y hace una copia saltando los primeros tres bytes:

public static void workAroundbrokenToolsAndAPIs(File sourceFile, File destFile) throws IOException { if(!destFile.exists()) { destFile.createNewFile(); } FileChannel source = null; FileChannel destination = null; try { source = new FileInputStream(sourceFile).getChannel(); source.position(3); destination = new FileOutputStream(destFile).getChannel(); destination.transferFrom( source, 0, source.size() - 3 ); } finally { if(source != null) { source.close(); } if(destination != null) { destination.close(); } } }

Tenga en cuenta que es "sin procesar": por lo general, primero querrá asegurarse de tener una lista de materiales antes de llamar a esto o "Malos pensamientos pueden suceder" [TM].

Puedes mirar tu archivo después:

... $ file /tmp/dst.txt /tmp/dst.txt: UTF-8 Unicode English text ... $ ls -l /tmp/dst.txt -rw-rw-r-- 1 tact tact 1730 2012-03-16 14:41 /tmp/dst.txt ... $ hexdump -C /tmp/dst.txt 00000000 50 6f 6b 65 ...

Y la lista de materiales se ha ido ...

Ahora, si simplemente desea eliminar de forma transparente la lista de materiales para una API de Java dañada, entonces puede usar el pushbackInputStream que se describe aquí: ¿por qué org.apache.xerces.parsers.SAXParser no omite la lista de materiales en el código xml codificado en utf8?

private static InputStream checkForUtf8BOMAndDiscardIfAny(InputStream inputStream) throws IOException { PushbackInputStream pushbackInputStream = new PushbackInputStream(new BufferedInputStream(inputStream), 3); byte[] bom = new byte[3]; if (pushbackInputStream.read(bom) != -1) { if (!(bom[0] == (byte) 0xEF && bom[1] == (byte) 0xBB && bom[2] == (byte) 0xBF)) { pushbackInputStream.unread(bom); } } return pushbackInputStream; }

Tenga en cuenta que esto funciona, pero definitivamente NO solucionará el problema más grave en el que puede tener otras herramientas en la cadena de trabajo que no funcionan correctamente con los archivos UTF-8 que tienen una lista de materiales.

Y aquí hay un enlace a una pregunta con una respuesta más completa, que abarca también otras codificaciones:

La marca de orden de bytes complica la lectura de archivos en Java

Necesito sugerencias sobre la forma de eliminar la lista de materiales de un archivo UTF-8 y crear una copia del resto del archivo xml.