Here is my code, imageFile
is a pdf
file, intent is to get Base64
encoded file for image file. I am using Java6
and no possibility to upgrade to Java7
Base64Inputstream
is of type 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;
}
I was using IOUtils.copy(InputStream input, Writer output)
method. But for some pdf
files (note, not all) it throws exception. So, in the process of debugging I copied IOUtils.copy
code locally and exception is thrown after Count: 2630388
. This is the stack trace:
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)
Under what situations can this block above said throw exception:
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
System.out.println("Count: " + count);
}
Please help me understand the cause and how can I fix it
You should not use Reader/Writer which are text oriented and not binary, at least without encoding. They use an encoding. And PDF is binary. Either explicitly given, or the default OS encoding (unportable).
For
InputStream
usereadFully
.And then do always a
close()
. Thecopy
method, maybe leaving the close to the callers, could at least callflush()
in that case.In Java 7 there already exists a copy, but needs a Path and an extra option.