使用Files.readAllLines()时出现的MalformedInputException

7

我正在迭代一些文件,准确来说是5328个。这些文件是平均带有60-200行最大行数的XML文件。它们首先通过一个简单的方法isXmlSourceFile进行过滤,该方法解析路径。

    Files.walk(Paths.get("/home/me/development/projects/myproject"), FileVisitOption.FOLLOW_LINKS)
            .filter(V3TestsGenerator::isXmlTestSourceFile)
            .filter(V3TestsGenerator::fileContainsXmlTag)

对于第二个过滤器,特别是fileContainsXmlTag方法,这是一个大问题。我想要检测每个文件中是否至少包含一次给定模式:

private static boolean fileContainsXmlTag(Path path) {
    try {
        return Files.readAllLines(path).stream().anyMatch(line -> PATTERN.matcher(line).find());
    } catch (IOException e) {
        e.printStackTrace();
    }
    return false;
}

对于一些文件,我会得到这个异常

java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at java.nio.file.Files.readAllLines(Files.java:3205)
at java.nio.file.Files.readAllLines(Files.java:3242)

但是当我使用FileUtiles.readLines()而不是Files.readAllLines()时,一切都正常了。

这只是一个好奇的问题,如果有人知道发生了什么,那就太好了。

谢谢

1个回答

16

方法Files.readAllLines()假设您要读取的文件采用UTF-8编码。

如果您遇到此异常,则您要读取的文件很可能采用与UTF-8不同的字符编码。

找出使用的字符编码,并使用另一个readAllLines方法,该方法允许您指定字符编码。

例如,如果文件采用ISO-8859-1编码:

return Files.readAllLines(path, StandardCharsets.ISO_8859_1).stream()... // etc.

FileUtiles.readLines()方法(它来自哪里?)可能假设其他情况(它可能假设文件使用您系统的默认字符编码,而不是UTF-8)。


我有同样的问题 - 我认为这与CR LF有关。 FileUtils.readLines(new File(filename), StandardCharsets.UTF_8) 对我来说运行良好,而Files.readAllLines(Paths.get(filename), StandardCharsets.UTF_8)则不行。 - Yost777
@Jesper 非常感谢你的回答! - Cousnouf
很奇怪,我用Notepad++编码为UTF-8的文件却收到了这个消息。所以我不同意这个答案。我怀疑@Yost777可能有答案。我可能正在Windows机器上读取在Unix平台上创建的文本文件并遇到了这个问题。但在我的情况下,我有这个语法:Files.readAllLines(Paths.get(fileName)); - JGFMK
1
ISO-8859-1 对我来说确实解决了这个问题。似乎中和了那个问题。 - JGFMK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接