Я создаю простую программу wordcount на Java, которая читает текстовые файлы каталога.
Однако я продолжаю получать ошибку:
java.nio.charset.MalformedInputException: Input length = 1
из этой строки кода:
BufferedReader reader = Files.newBufferedReader(file,Charset.forName("UTF-8"));
Я знаю, что, вероятно, получил это, потому что я использовал, Charset
который не включал некоторые символы в текстовых файлах, некоторые из которых включали символы других языков. Но я хочу включить этих персонажей.
Позже в JavaDocs я узнал, что Charset
это необязательно и используется только для более эффективного чтения файлов, поэтому я изменил код на:
BufferedReader reader = Files.newBufferedReader(file);
Но некоторые файлы все равно закидывают MalformedInputException
. Не знаю почему.
Мне было интересно, есть ли комплексное Charset
решение, которое позволит мне читать текстовые файлы с разными типами символов ?
Спасибо.
источник
ISO-8859-1
и все работает хорошо. Я думаю, это для европейских персонажей, и это нормально. Но я до сих пор не знаю, почемуUTF-16
не работает.ISO-8859-1
, то это не такUTF-16
. Эти кодировки совершенно разные. Файл не может быть тем и другим.Создание BufferedReader из Files.newBufferedReader
Files.newBufferedReader(Paths.get("a.txt"), StandardCharsets.UTF_8);
при запуске приложения может возникнуть следующее исключение:
java.nio.charset.MalformedInputException: Input length = 1
Но
new BufferedReader(new InputStreamReader(new FileInputStream("a.txt"),"utf-8"));
работает хорошо.
Другое дело, что первый использует действие по умолчанию CharsetDecoder.
в то время как последний использует действие REPLACE.
источник
ISO-8859-1 - это всеобъемлющая кодировка в том смысле, что она гарантированно не генерирует исключение MalformedInputException. Так что это хорошо для отладки, даже если ваш ввод не в этой кодировке. Так:-
req.setCharacterEncoding("ISO-8859-1");
У меня было несколько символов двойной правой кавычки / двойной левой кавычки в моем вводе, и как US-ASCII, так и UTF-8 выдавали на них MalformedInputException, но ISO-8859-1 работал.
источник
Я также столкнулся с этим исключением с сообщением об ошибке,
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)
и обнаружил, что при попытке использовать
для записи преобразования String "orazg 54" из универсального типа в классе.
//key is of generic type <Key extends Comparable<Key>> writer.write(item.getKey() + "\t" + item.getValue() + "\n");
Эта строка имеет длину 9, содержащую символы со следующими кодовыми точками:
111 114 97 122 103 9 53 52 10
Однако, если BufferedWriter в классе заменяется на:
FileOutputStream outputStream = new FileOutputStream(filePath); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));
он может успешно записать эту строку без исключений. Кроме того, если я напишу ту же строку, созданную из символов, она все равно будет работать нормально.
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();
Раньше я никогда не сталкивался с какими-либо исключениями при использовании первого BufferedWriter для записи каких-либо строк. Это странная ошибка, которая возникает с BufferedWriter, созданным из java.nio.file.Files.newBufferedWriter (путь, параметры)
источник
ISO_8859_1 У меня сработало! Я читал текстовый файл со значениями, разделенными запятыми
источник
попробуйте это .. у меня была такая же проблема, ниже реализация работала для меня
затем используйте Reader где угодно.
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(); }
источник
Я написал следующее, чтобы распечатать стандартный список результатов на основе доступных кодировок. Обратите внимание, что он также сообщает вам, какая строка выходит из строя из номера строки, основанного на 0, в случае, если вы устраняете неполадки, какой символ вызывает проблемы.
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); } }
источник
Ну проблема в том, что
Files.newBufferedReader(Path path)
реализовано так:public static BufferedReader newBufferedReader(Path path) throws IOException { return newBufferedReader(path, StandardCharsets.UTF_8); }
так что в основном нет смысла указывать,
UTF-8
если вы не хотите быть описательным в своем коде. Если вы хотите попробовать «более широкую» кодировку, вы можете попробоватьStandardCharsets.UTF_16
, но вы все равно не можете быть на 100% уверены, что получите все возможные символы.источник
вы можете попробовать что-то подобное или просто скопировать и вставить фрагмент ниже.
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 ++; } }
источник
while(exception)
цикл навсегда, если он никогда не найдет рабочую кодировку в массиве. Обработчик исключений должен сгенерировать заново, если достигнут конец массива и рабочая кодировка не найдена. Кроме того, на момент написания этот ответ имел «-2» голоса. Я проголосовал за "-1". Я думаю, что причина, по которой он получил отрицательные голоса, заключается в недостаточном объяснении. Я понимаю, что делает код, а другие - нет. Поэтому комментарий типа «вы можете попробовать что-то подобное» может не понравиться некоторым людям.UTF-8 у меня работает с польскими символами
источник