Estoy creando un programa de conteo de palabras simple en Java que lee los archivos basados en texto de un directorio.
Sin embargo, sigo recibiendo el error:
java.nio.charset.MalformedInputException: Input length = 1
de esta línea de código:
BufferedReader reader = Files.newBufferedReader(file,Charset.forName("UTF-8"));
Sé que probablemente entiendo esto porque utilicé un Charset
que no incluía algunos de los caracteres en los archivos de texto, algunos de los cuales incluían caracteres de otros idiomas. Pero quiero incluir esos personajes.
Más tarde supe en JavaDocs que Charset
es opcional y solo se usa para una lectura más eficiente de los archivos, así que cambié el código a:
BufferedReader reader = Files.newBufferedReader(file);
Pero algunos archivos todavía arrojan el MalformedInputException
. No sé por qué.
Me preguntaba si hay un todo incluido Charset
que me permita leer archivos de texto con muchos tipos diferentes de caracteres .
Gracias.
fuente
ISO-8859-1
y funciona bien. Creo que es para personajes europeos, lo cual está bien. Sin embargo, todavía no sé por quéUTF-16
no funciona.ISO-8859-1
, entonces es noUTF-16
. Estas codificaciones son completamente diferentes. Un archivo no puede ser ambos.Creación de BufferedReader a partir de Files.newBufferedReader
Files.newBufferedReader(Paths.get("a.txt"), StandardCharsets.UTF_8);
al ejecutar la aplicación, puede producir la siguiente excepción:
java.nio.charset.MalformedInputException: Input length = 1
Pero
new BufferedReader(new InputStreamReader(new FileInputStream("a.txt"),"utf-8"));
funciona bien.
La diferencia es que, el primero usa la acción predeterminada CharsetDecoder.
mientras que este último usa la acción REPLACE.
fuente
ISO-8859-1 es un conjunto de caracteres con todo incluido, en el sentido de que está garantizado que no arrojará MalformedInputException. Por lo tanto, es bueno para la depuración, incluso si su entrada no está en este juego de caracteres. Entonces:-
req.setCharacterEncoding("ISO-8859-1");
Tenía algunos caracteres de comillas dobles a la derecha / comillas dobles a la izquierda en mi entrada, y tanto US-ASCII como UTF-8 arrojaron MalformedInputException en ellos, pero ISO-8859-1 funcionó.
fuente
También encontré esta excepción con un mensaje de error,
java.nio.charset.MalformedInputException: Input length = 1 at java.nio.charset.CoderResult.throwException(Unknown Source) at sun.nio.cs.StreamEncoder.implWrite(Unknown Source) at sun.nio.cs.StreamEncoder.write(Unknown Source) at java.io.OutputStreamWriter.write(Unknown Source) at java.io.BufferedWriter.flushBuffer(Unknown Source) at java.io.BufferedWriter.write(Unknown Source) at java.io.Writer.write(Unknown Source)
y descubrió que se produce un error extraño al intentar usar
para escribir una cadena "orazg 54" de un tipo genérico en una clase.
//key is of generic type <Key extends Comparable<Key>> writer.write(item.getKey() + "\t" + item.getValue() + "\n");
Esta cadena tiene una longitud de 9 y contiene caracteres con los siguientes puntos de código:
111114 97122103 9 53 52 10
Sin embargo, si el BufferedWriter de la clase se reemplaza por:
FileOutputStream outputStream = new FileOutputStream(filePath); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));
puede escribir correctamente esta cadena sin excepciones. Además, si escribo la misma cadena creada a partir de los caracteres, todavía funciona bien.
String string = new String(new char[] {111, 114, 97, 122, 103, 9, 53, 52, 10}); BufferedWriter writer = Files.newBufferedWriter(Paths.get("a.txt")); writer.write(string); writer.close();
Anteriormente, nunca había encontrado ninguna excepción al usar el primer BufferedWriter para escribir cadenas. Es un error extraño que le ocurre a BufferedWriter creado a partir de java.nio.file.Files.newBufferedWriter (ruta, opciones)
fuente
¡ISO_8859_1 funcionó para mí! Estaba leyendo un archivo de texto con valores separados por comas
fuente
prueba esto ... tuve el mismo problema, la implementación a continuación funcionó para mí
luego use Reader donde quiera.
foreg:
CsvToBean<anyPojo> csvToBean = null; try { Reader reader = Files.newBufferedReader(Paths.get(csvFilePath), StandardCharsets.ISO_8859_1); csvToBean = new CsvToBeanBuilder(reader) .withType(anyPojo.class) .withIgnoreLeadingWhiteSpace(true) .withSkipLines(1) .build(); } catch (IOException e) { e.printStackTrace(); }
fuente
Escribí lo siguiente para imprimir una lista de resultados a la salida estándar basada en los juegos de caracteres disponibles. Tenga en cuenta que también le indica qué línea falla de un número de línea basado en 0 en caso de que esté solucionando el carácter que está causando problemas.
public static void testCharset(String fileName) { SortedMap<String, Charset> charsets = Charset.availableCharsets(); for (String k : charsets.keySet()) { int line = 0; boolean success = true; try (BufferedReader b = Files.newBufferedReader(Paths.get(fileName),charsets.get(k))) { while (b.ready()) { b.readLine(); line++; } } catch (IOException e) { success = false; System.out.println(k+" failed on line "+line); } if (success) System.out.println("************************* Successs "+k); } }
fuente
Bueno, el problema es que
Files.newBufferedReader(Path path)
se implementa así:public static BufferedReader newBufferedReader(Path path) throws IOException { return newBufferedReader(path, StandardCharsets.UTF_8); }
así que básicamente no tiene sentido especificar a
UTF-8
menos que desee ser descriptivo en su código. Si quieres probar un juego de caracteres "más amplio", puedes intentarloStandardCharsets.UTF_16
, pero no puedes estar 100% seguro de obtener todos los caracteres posibles de todos modos.fuente
puede probar algo como esto, o simplemente copiar y pegar la siguiente pieza.
boolean exception = true; Charset charset = Charset.defaultCharset(); //Try the default one first. int index = 0; while(exception) { try { lines = Files.readAllLines(f.toPath(),charset); for (String line: lines) { line= line.trim(); if(line.contains(keyword)) values.add(line); } //No exception, just returns exception = false; } catch (IOException e) { exception = true; //Try the next charset if(index<Charset.availableCharsets().values().size()) charset = (Charset) Charset.availableCharsets().values().toArray()[index]; index ++; } }
fuente
while(exception)
bucle para siempre si nunca encuentra un juego de caracteres que funcione en la matriz. El controlador de excepciones debería volver a lanzar si se alcanza el final de la matriz y no se encuentra ningún juego de caracteres que funcione. Además, en el momento de redactar este informe, esta respuesta tenía "-2" votos. Lo he votado a "-1". Creo que la razón por la que obtuvo votos negativos es porque no hay una explicación suficiente. Si bien entiendo lo que hace el código, es posible que otras personas no. Por lo tanto, es posible que algunas personas no aprecien un comentario como "puedes probar algo como esto".UTF-8 me funciona con caracteres polacos
fuente