Java Files.readAllBytes vs Files.lines格式错误InputException

Java Files.readAllBytes vs Files.lines格式错误InputException,java,file-io,stream,Java,File Io,Stream,我本以为以下两种读取文件的方法应该表现得相同。但他们没有。第二种方法是抛出一个格式错误的putException public static void main(String[] args) { try { String content = new String(Files.readAllBytes(Paths.get("_template.txt"))); System.out.println(content); } catch (IOE

我本以为以下两种读取文件的方法应该表现得相同。但他们没有。第二种方法是抛出一个
格式错误的putException

public static void main(String[] args) {    
    try {
        String content = new String(Files.readAllBytes(Paths.get("_template.txt")));
        System.out.println(content);
    } catch (IOException e) {
        e.printStackTrace();
    }

    try(Stream<String> lines = Files.lines(Paths.get("_template.txt"))) {
        lines.forEach(System.out::println);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

这里的区别是什么?如何修复它?

文件。默认情况下,行使用,而从字节实例化新字符串将使用默认的系统编码。您的文件似乎不在UTF-8中,这就是它失败的原因

检查文件使用的编码,并将其作为第二个参数传递。

这与。计算机只处理数字。要存储文本,必须使用某种方案将文本中的字符与数字进行转换。这种方案称为字符编码。有许多不同的字符编码;一些著名的标准字符编码是ASCII、ISO-8859-1和UTF-8

在第一个示例中,您读取文件中的所有字节(数字),然后通过将它们传递给类
String
的构造函数将它们转换为字符。这将使用系统的默认字符编码(无论在操作系统上是什么)将字节转换为字符

在第二个示例中,如果使用
文件.lines(…)
,则将根据使用UTF-8字符编码。当在文件中发现一个字节序列不是有效的UTF-8序列时,您将得到一个
格式不正确的putException

public static void main(String[] args) {    
    try {
        String content = new String(Files.readAllBytes(Paths.get("_template.txt")));
        System.out.println(content);
    } catch (IOException e) {
        e.printStackTrace();
    }

    try(Stream<String> lines = Files.lines(Paths.get("_template.txt"))) {
        lines.forEach(System.out::println);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
系统的默认字符编码可能是UTF-8,也可能不是UTF-8,因此可以解释行为上的差异

您必须找出文件使用的是什么字符编码,然后显式地使用它。例如:

String content = new String(Files.readAllBytes(Paths.get("_template.txt")),
        StandardCharsets.ISO_8859_1);
第二个例子:

Stream<String> lines = Files.lines(Paths.get("_template.txt"),
        StandardCharsets.ISO_8859_1);
streamlines=Files.lines(path.get(“\u template.txt”),
标准字符集(ISO_8859_1);
作为补充,这里发生的事情(未记录!)是
Files.lines()
创建一个文件,其策略是拒绝无效的字节序列;也就是说,它被设置为
报告

这与JDK提供的几乎所有其他
Reader
实现不同,JDK的标准策略是
REPLACE
。此策略将导致所有不可映射的字节序列发出一个错误。

2017使用:

 Charset.forName("ISO_8859_1") instead of Charsets.ISO_8859_1

一种方法读取字节,一种方法读取文本。你的文件是文本文件吗?编码是什么?此外,
Files.lines()
的默认编码是UTF-8。不是每个字节序列都是有效的UTF-8。我想我需要一些帮助来回答你的问题。该文件是一个文本文件。使用Notepad++打开,状态栏中显示ANSI。这能回答你的问题吗?@Phylogenesis谢谢你的链接。我以前确实读过。我最近决定再读一遍。也许现在是阅读它的合适时机:-有趣。。。这意味着
Files.lines()
中使用的
CharsetDecoder
默认使用
CodingErrorAction.REPORT
。这没有文档记录,与JDK提供的任何默认
读取器不同…@fge
Files.lines()
从传递给它的
Charset
创建
CharsetDecoder
,而
CharsetDecoder
的默认操作是报告格式错误的输入和不可复制的字符错误,在JDK:@fge中,这个默认操作几乎处处都被覆盖。我想较旧的
Reader
类在向后兼容性方面做得不同。(同样奇怪的是,
Files.lines()
默认使用UTF-8,而大多数其他I/O类默认使用系统的默认字符集)。标准类在很多方面都不太一致……您能添加更多细节吗?@Angelo.Hannes这样使用它:Stream Stream=Files.lines(path.get(“/User/me/file.log”)、Charset.forName(“ISO_8859_1”))