java.io.IOException的原因是什么:底层输入流返回零字节

java.io.IOException的原因是什么:底层输入流返回零字节,java,pdf,file-io,base64,ioexception,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() + " toBas

这是我的代码,
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输入,Writer输出)
方法。但对于一些
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)
在什么情况下,上述块可以引发异常:

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

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

您不应使用面向文本且非二进制的读写器,至少不应使用编码。它们使用编码。PDF是二进制的。要么显式给定,要么默认操作系统编码(不可移植)

对于
InputStream
使用
readFully

然后始终执行
close()
。在这种情况下,
copy
方法可能会让调用方靠近,至少可以调用
flush()


在Java7中已经存在一个,但需要一个路径和一个额外的选项

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;
}

请详细说明建议更改的代码段。谢谢,说得好。OP应该放弃FileWriter并使用FileOutputStream。OP不需要完全使用,只需放弃读写器即可。@Learner我已使用现有函数添加了“最佳”解决方案。您没有说Java 7是否正常。谢谢@jtahlborn。。你的评论实际上对我来说是一个有效的答案。它在切换到
FileOutputStream
而不是
FileWriter
后工作。