全部包含 Charset 以避免“ java.nio.Charset. MalformedInputException: Input length = 1”?

我正在用 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,它允许我读取带有许多不同类型字符 的文本文件?

谢谢。

193268 次浏览

You probably want to have a list of supported encodings. For each file, try each encoding in turn, maybe starting with UTF-8. Every time you catch the MalformedInputException, try the next encoding.

我还遇到了这个错误消息的异常,

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)

发现一些奇怪的错误时,试图使用

BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath));

从类中的泛型类型编写字符串“ orazg 54”强制转换。

//key is of generic type <Key extends Comparable<Key>>
writer.write(item.getKey() + "\t" + item.getValue() + "\n");

This String is of length 9 containing chars with the following code points:

114 97 122 103 9 53 52 10

但是,如果类中的 BufferedWriter 被替换为:

FileOutputStream outputStream = new FileOutputStream(filePath);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));

它可以毫无例外地成功地编写这个 String。此外,如果我从字符中编写相同的 String 创建,它仍然可以工作。

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 编写字符串时,我从未遇到过任何异常。从 java.nio.file 创建的 BufferedWriter 出现了一个奇怪的 bug。NewBufferedWriter (路径,选项)

问题是 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 ++;
}
}

Creating BufferedReader from 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"));

效果不错。

不同之处在于,前者使用 CharsetDecode 默认操作。

The default action for malformed-input and unmappable-character errors is to 报告 them.

而后者使用 REPLACE 操作。

cs.newDecoder().onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE)

我编写了以下代码,根据可用的字符集打印一个标准输出的结果列表。请注意,它还告诉您哪一行从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);
}
}

ISO-8859-1 is an all-inclusive charset, in the sense that it's guaranteed not to throw MalformedInputException. So it's good for debugging, even if your input is not in this charset. So:-

req.setCharacterEncoding("ISO-8859-1");

I had some double-right-quote/double-left-quote characters in my input, and both US-ASCII and UTF-8 threw MalformedInputException on them, but ISO-8859-1 worked.

试试这个. . 我有同样的问题,下面的实施为我工作

Reader reader = Files.newBufferedReader(Paths.get(<yourfilewithpath>), StandardCharsets.ISO_8859_1);

然后在任何你想要的地方使用 Reader。

前言:

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();
}

ISO _ 8859 _ 1对我很有用! 我正在阅读逗号分隔值的文本文件

UTF-8为我工作与波兰字符