bominputstream - ufeff java
Lectura UTF-8-marcador BOM (9)
Así es como uso Apache BOMInputStream, usa un bloque try-with-resources. El argumento "falso" le dice al objeto que ignore las siguientes listas de materiales (utilizamos archivos de texto "BOM-less" por razones de seguridad, jaja):
try( BufferedReader br = new BufferedReader(
new InputStreamReader( new BOMInputStream( new FileInputStream(
file), false, ByteOrderMark.UTF_8,
ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_16LE,
ByteOrderMark.UTF_32BE, ByteOrderMark.UTF_32LE ) ) ) )
{
// use br here
} catch( Exception e)
}
Estoy leyendo un archivo a través de un FileReader - el archivo está decodificado en UTF-8 (con BOM) ahora mi problema es: leo el archivo y saco una cadena, pero tristemente el marcador BOM también se saca. ¿Por qué ocurre esto?
fr = new FileReader(file);
br = new BufferedReader(fr);
String tmp = null;
while ((tmp = br.readLine()) != null) {
String text;
text = new String(tmp.getBytes(), "UTF-8");
content += text + System.getProperty("line.separator");
}
salida después de la primera línea
?<style>
Considera UnicodeReader de Google, que hace todo este trabajo por ti.
Charset utf8 = Charset.forName("UTF-8"); // default if no BOM present
try (Reader r = new UnicodeReader(new FileInputStream(file), utf8)) {
....
}
Dependencia de Maven:
<dependency>
<groupId>com.google.gdata</groupId>
<artifactId>core</artifactId>
<version>1.47.1</version>
</dependency>
En Java, debe consumir manualmente la BOM UTF8 si está presente. Este comportamiento está documentado en la base de datos de errores de Java, here y here . No habrá una solución por ahora porque romperá las herramientas existentes como los analizadores JavaDoc o XML. Apache IO Commons proporciona un BOMInputStream
para manejar esta situación.
Eche un vistazo a esta solución: Maneje el archivo UTF8 con BOM
La forma más fácil que encontré para pasar por alto la lista de materiales
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
while ((currentLine = br.readLine()) != null) {
//case of, remove the BOM of UTF-8 BOM
currentLine = currentLine.replace("","");
La solución más sencilla probablemente sea eliminar el /uFEFF
resultante de la cadena, ya que es muy poco probable que aparezca por cualquier otro motivo.
tmp = tmp.replace("/uFEFF", "");
Ver también este informe de error de guayaba
Luego se me ocurrió esta subclase Reader
/*
* Copyright (C) 2016 donizyo
*
*/
package net.donizyo.io;
public class BOMReader extends BufferedReader {
public static final String DEFAULT_ENCODING = "UTF-8";
public BOMReader(File file) throws IOException {
this(file, DEFAULT_ENCODING);
}
private BOMReader(File file, String encoding) throws IOException {
this(new FileInputStream(file), encoding);
}
private BOMReader(FileInputStream input, String encoding) throws IOException {
this(new BOMInputStream(input), encoding);
}
private BOMReader(BOMInputStream input, String encoding) throws IOException {
super(new InputStreamReader(input, getCharset(input, encoding)));
}
private static String getCharset(BOMInputStream bomInput, String encoding) throws IOException {
ByteOrderMark bom;
bom = bomInput.getBOM();
return bom == null ? encoding : bom.getCharsetName();
}
}
Se menciona here que esto suele ser un problema con los archivos en Windows.
Una posible solución sería ejecutar el archivo a través de una herramienta como dos2unix primero.
Use la biblioteca de Apache Commons .
Clase: org.apache.commons.io.input.BOMInputStream
Ejemplo de uso:
String defaultEncoding = "UTF-8";
InputStream inputStream = new FileInputStream(someFileWithPossibleUtf8Bom);
try {
BOMInputStream bOMInputStream = new BOMInputStream(inputStream);
ByteOrderMark bom = bOMInputStream.getBOM();
String charsetName = bom == null ? defaultEncoding : bom.getCharsetName();
InputStreamReader reader = new InputStreamReader(new BufferedInputStream(bOMInputStream), charsetName);
//use reader
} finally {
inputStream.close();
}
Utilice Apache Commons IO .
Por ejemplo, echemos un vistazo a mi código (usado para leer un archivo de texto con caracteres latinos y cirílicos) a continuación:
String defaultEncoding = "UTF-16";
InputStream inputStream = new FileInputStream(new File("/temp/1.txt"));
BOMInputStream bomInputStream = new BOMInputStream(inputStream);
ByteOrderMark bom = bomInputStream.getBOM();
String charsetName = bom == null ? defaultEncoding : bom.getCharsetName();
InputStreamReader reader = new InputStreamReader(new BufferedInputStream(bomInputStream), charsetName);
int data = reader.read();
while (data != -1) {
char theChar = (char) data;
data = reader.read();
ari.add(Character.toString(theChar));
}
reader.close();
Como resultado, tenemos un ArrayList llamado "ari" con todos los caracteres del archivo "1.txt", excepto la lista de materiales.