MalformedInputException:运行两次时输入长度= 1

问题描述 投票:0回答:2

使用此代码运行文件在第一次运行时效果很好,但在第二次运行时(在同一文件上),Files.readAllLines抛出异常。

所有代码都是(对于每个文件,但在这种情况下它只是一个)从文件中获取所有行,删除它,然后使用相同的内容重新填充它。

for (File file : content) {
    List<String> fillLines = new ArrayList<>();
    try {
        fillLines = Files.readAllLines(file.toPath());
    } catch (IOException e) {
        e.printStackTrace();
    }

    if (fillLines.size() > 0) {
        file.delete();
        FileWriter fileWriter = new FileWriter(file, false);

        for (String line : fillLines) {
            fileWriter.write(line);
            if (fillLines.indexOf(line) < fillLines.size() - 1)
                fileWriter.append(System.lineSeparator());
        }
        fileWriter.close();
    }
}

有任何想法吗?可能是因为fileWriter.append(System.lineSeparator());

所有其他的被问者都是第一次失败,因为用错误的字符集阅读它。但是,由于我能够运行一次,我不是在阅读,而是写错了,所以更改字符集似乎是一种可以避免的解决方法。

堆栈跟踪:

java.nio.charset.MalformedInputException: Input length = 1
    at java.nio.charset.CoderResult.throwException(Unknown Source)
    at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
    at sun.nio.cs.StreamDecoder.read(Unknown Source)
    at java.io.InputStreamReader.read(Unknown Source)
    at java.io.BufferedReader.fill(Unknown Source)
    at java.io.BufferedReader.readLine(Unknown Source)
    at java.io.BufferedReader.readLine(Unknown Source)
    at java.nio.file.Files.readAllLines(Unknown Source)
    at java.nio.file.Files.readAllLines(Unknown Source)

这里的任何东西都指向

    fillLines = Files.readAllLines(file.toPath());
java file filewriter
2个回答
4
投票

Files.readAllLines()的文档:

使用UTF-8字符集将文件中的字节解码为字符

FileWriter的文档:

此类的构造函数假定默认字符编码和默认字节缓冲区大小是可接受的。要自己指定这些值,请在FileOutputStream上构造OutputStreamWriter。

因此,您使用默认平台编码(在您的情况下,不是UTF8)和使用UTF8进行读取。这是例外的原因。使用相同的编码进行写入和读取。上述文档说明了如何指定要写入的UTF8编码。


0
投票
for (File file : content) {
    Path path = fiel.toPath();
    List<String> fillLines;
    try {
        fillLines = Files.readAllLines(path);
    } catch (IOException e) {
        System.err.println("Error while reading " + path);
        e.printStackTrace();
        fillLines = new ArrayList<>();
    }

    if (!fillLines.isEmpty()) {
        //Files.delete(path);
        // See -A-
        Files.write(path, fillLines, StandardOpenOptions.TRUNCATE_EXISTING);
    }
}

为什么这样 - 即使它更短,更安全,更一致?

错误

您没有指明Charset进行阅读和写作。

Files之前,这意味着使用了平台编码,并且存在带有Charset / String编码的重载构造函数。

对于非常古老的FileReader/FileWriter,即使不存在重载:它们总是使用平台编码 - System.getProperty("file.encoding")

使用Files Unicode的UTF-8成为默认值:由于java String包含Unicode,转换变为无损。大!

但是在使用像Windows-1252这样的东西后,用UTF-8读取可能会失败,因为UTF-8要求第8位专门用于实现有效的多字节序列。

注意:最初文件是UTF-8,但一旦编写,就不再是(没有有效的UTF-8)。

// -A-
// Possibly add a BOM (begin of file marker) to identify to Windows
// that this file is in UTF-8 (works for UTF-16 too).
// This is primarily for Notepad. A BOM is redundant, invisible (zero width space)
// and generally inadvisable if not needed.
if (!lines.get(0).startsWith("\uFEFF")) {
    lines.set(0, "\uFEFF" + lines.get(0));
}
© www.soinside.com 2019 - 2024. All rights reserved.