java - java.io.IOException : Underlying input stream returned zero bytes 的原因是什么

标签 java pdf file-io base64 ioexception

这是我的代码,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);
                }

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

最佳答案

您不应该使用面向文本而非二进制的读取器/写入器,至少不应该使用编码。他们使用编码。并且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;
}

关于java - java.io.IOException : Underlying input stream returned zero bytes 的原因是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18703240/

相关文章:

java - 是什么导致了这个mockito异常?

java - 服务器端的 Cookie 不起作用

ios - 运行 iOS 应用程序时,矢量图像以灰度显示

linux - 合并/合并多个 PDF 文件

matlab - 来自 matlab 的制表符分隔文本文件

java - 将 2 维数组 String 转换为 2 维数组 Double

java - jfree 图表 org.jfree.chart.plot.CategoryPlot 无法转换为 org.jfree.chart.plot.XYPlot

java - 使用 PdfDocument 在 Android 中生成自定义尺寸的 PDF

java - 为什么这段代码不读取我的文件?

C#加密解密IV题