【问题标题】:What is the reason for java.io.IOException: Underlying input stream returned zero bytesjava.io.IOException的原因是什么:基础输入流返回零字节
【发布时间】:2013-09-13 05:42:12
【问题描述】:

这是我的代码,imageFile 是一个pdf 文件,目的是获取图像文件的Base64 编码文件。我正在使用Java6,无法升级到Java7

Base64Inputstream 的类型为 org.apache.commons.codec.binary.Base64InputStream

private File toBase64(File imageFile) throws Exception {
         LOG.info(this.getClass().getName() + " toBase64 method is called");
         System. out.println("toBase64 is called" );
         Base64InputStream in = new Base64InputStream(new FileInputStream(imageFile), true );
         File f = new File("/root/temp/" + imageFile.getName().replaceFirst("[.][^.]+$" , "" ) + "_base64.txt" );
         Writer out = new FileWriter(f);
         copy(in, out);
         return f;
  }

 private void copy(InputStream input, Writer output)
            throws IOException {
        InputStreamReader in = new InputStreamReader(input);
        copy(in, output);
    }

 private int copy(Reader input, Writer output) throws IOException {
        long count = copyLarge(input, output);
        if (count > Integer.MAX_VALUE) {
            return -1;
        }
        return (int) count;
    }

 private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;

 private long copyLarge(Reader input, Writer output) {
        char[] buffer = new char[DEFAULT_BUFFER_SIZE];
        long count = 0;
        int n = 0;
        try {
            while (-1 != (n = input.read(buffer))) {
                output.write(buffer, 0, n);
                count += n;
                System.out.println("Count: " + count);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return count;
    }

我使用的是IOUtils.copy(InputStream input, Writer output) 方法。但是对于一些pdf 文件(注意,不是全部)它会抛出异常。因此,在调试过程中,我在本地复制了IOUtils.copy 代码,并在Count: 2630388 之后引发了异常。这是堆栈跟踪:

Root Exception stack trace:
java.io.IOException: Underlying input stream returned zero bytes
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:268)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)

上面所说的这个block在什么情况下会抛出异常:

while (-1 != (n = input.read(buffer))) {
                    output.write(buffer, 0, n);
                    count += n;
                    System.out.println("Count: " + count);
                }

请帮助我了解原因以及如何解决它

【问题讨论】:

    标签: java pdf file-io base64 ioexception


    【解决方案1】:

    你不应该使用面向文本而不是二进制的Reader/Writer,至少没有编码。他们使用编码。 PDF是二进制的。要么明确给出,要么默认操作系统编码(不可移植)。

    对于InputStream,请使用readFully

    然后总是使用close()copy 方法,可能把 close 留给调用者,在这种情况下至少可以调用 flush()


    在 Java 7 中已经存在 copy,但需要一个路径和一个额外的选项。

    private File toBase64(File imageFile) throws Exception {
        LOG.info(this.getClass().getName() + " toBase64 method is called");
        System.out.println("toBase64 is called");
        Base64InputStream in = new Base64InputStream(new FileInputStream(imageFile),
            true);
        File f = new File("/root/temp/" + imageFile.getName()
            .replaceFirst("[.][^.]+$", "") + "_base64.txt");
    
        Files.copy(in, f.toPath(), StandardCopyOption.REPLACE_EXISTING);
        in.close();
    
        return f;
    }
    

    【讨论】:

    • 您能否详细说明代码 sn-p 以建议更改。谢谢
    • 哦,好点。 OP 应该放弃 FileWriter 并使用 FileOutputStream。
    • OP 不需要使用 readFully,只需抛弃 Reader/Writer。
    • @Learner 我使用现有函数添加了“最佳”解决方案。你没有说 Java 7 好不好。
    • 谢谢@jtahlborn .. 你的评论对我来说实际上是一个有效的答案。它在切换到FileOutputStream 而不是FileWriter 后工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    相关资源
    最近更新 更多