首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Files.readAllBytes对Files.lines getting

Files.readAllBytes对Files.lines getting
EN

Stack Overflow用户
提问于 2015-04-29 07:55:39
回答 4查看 29.2K关注 0票数 19

我认为以下两种读取文件的方法应该是一样的。但事实并非如此,第二种方法是抛出一个MalformedInputException

代码语言:javascript
复制
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();
    }
}

这是堆栈跟踪:

代码语言:javascript
复制
Exception in thread "main" java.io.UncheckedIOException: java.nio.charset.MalformedInputException: Input length = 1
    at java.io.BufferedReader$1.hasNext(BufferedReader.java:574)
    at java.util.Iterator.forEachRemaining(Iterator.java:115)
    at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
    at Test.main(Test.java:19)
Caused by: 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.io.BufferedReader$1.hasNext(BufferedReader.java:571)
    ... 4 more

这里有什么不同,我该如何解决呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-04-29 08:01:44

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

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

在第二个示例中,在使用Files.lines(...)的情况下,根据文献资料,将使用UTF-8字符编码。当在文件中找到一个不是有效UTF-8序列的字节序列时,您将得到一个MalformedInputException

系统的默认字符编码可能是UTF-8,也可能不是UTF-8,因此可以解释行为的差异。

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

代码语言:javascript
复制
String content = new String(Files.readAllBytes(Paths.get("_template.txt")),
        StandardCharsets.ISO_8859_1);

第二个例子:

代码语言:javascript
复制
Stream<String> lines = Files.lines(Paths.get("_template.txt"),
        StandardCharsets.ISO_8859_1);
票数 35
EN

Stack Overflow用户

发布于 2015-04-29 08:17:41

为了补充杰斯珀的回答,这里发生了什么(而且是没有文档的!)是Files.lines()创建了一个CharsetDecoder,其策略是拒绝无效的字节序列;也就是说,它的CodingErrorAction设置为REPORT

这与JDK提供的几乎所有其他Reader实现不同,JDK的标准策略是REPLACE。此策略将导致所有不可映射的字节序列发出替换字符(U+FFFD)

票数 6
EN

Stack Overflow用户

发布于 2015-04-29 08:01:31

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29937600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档