java.nio.charset.MalformedInputException: 输入长度=1

26

我有这个函数(去掉了代码示例的HTML标签),它可以将CSV构建成一个HTML表格,但每次尝试运行它时,都会出现运行时错误,我不知道为什么。谷歌说可能是编码有问题,但我不知道如何更改。

我的CSV是ANSI编码,并包含像ä、Ä、Ü、Ö这样的字符,但我无法控制编码或将来是否会更改。

错误发生在这里:

Caused by: java.io.UncheckedIOException: java.nio.charset.MalformedInputException: Input length = 1
at java.io.BufferedReader$1.hasNext(Unknown Source)
at java.util.Iterator.forEachRemaining(Unknown Source)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
at java.util.stream.ReferencePipeline$Head.forEach(Unknown Source)
at testgui.Csv2Html.start(Csv2Html.java:121)

第121行是

lines.forEach(line -> {

源代码:

protected void start() throws Exception {

    Path path = Paths.get(inputFile);

    FileOutputStream fos = new FileOutputStream(outputFile, true);
    PrintStream ps = new PrintStream(fos);      

    boolean withTableHeader = (inputFile.length() != 0);
    try  {
        Stream<String> lines = Files.lines(path);
        lines.forEach(line -> {
            try {
                String[] columns = line.split(";");
                for (int i=0; i<columns.length; i++) {
                    columns[i] = escapeHTMLChars(columns[i]);
                }       
                if (withTableHeader == true && firstLine == true) {
                    tableHeader(ps, columns);
                    firstLine = false;
                } else {
                    tableRow(ps, columns);
                }


            } catch (Exception e) {
                e.printStackTrace();
            } finally {

            }
        });

    } finally {
        ps.close();
    }

}

对于当前(和未来)的参考:如果您告诉我们异常发生在哪行代码上,那将非常有帮助。 - Tim Biegeleisen
每次我尝试运行它时,都会出现运行时错误。是哪种错误?请分享一下。 - akash
1
抱歉,添加了异常的相关部分和行号。 - Vega
1个回答

41
你可以尝试使用Files.lines(Path path, Charset charset)形式的lines方法(javadocs)来利用正确的编码。
这里是支持的编码列表(至少适用于Oracle JVM)。此帖子指出,“Cp1252”是Windows ANSI。在这里查看

4
谢谢,问题解决了 :) - Stream<String> lines = Files.lines(Paths.get(inputFile), Charset.forName("Cp1252")); 你知道我应该在哪里关闭我的Stream吗?Eclipse警告我存在资源泄漏,因为我没有调用lines.close(),但是我不知道该把它放在哪里,尝试了finally {}块,但这给了我一个异常,似乎我关闭了Stream太早。 - Vega
4
您可以使用try-with-resources来在流使用完成后自动关闭它:https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html使用try-with-resources语句块,您可以在代码执行完毕后自动关闭文件流,并避免资源泄漏的问题,示例代码如下:try (Stream<String> lines = Files.lines(Paths.get(inputFile), Charset.forName("Cp1252")) { // 这里是您的解析代码 } - blazetopher
1
感谢您的回复。关于如何解决这个问题,我也遇到了同样的情况,当使用流读取文件时,实现错误没有显示出来,所以让我很疯狂。感谢您展示了Stream API处理不同编码的CSV文件的方法。 - Gabriel Hernandez

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