使用流式传输的Android文件到Base64有时会错过2个字节

我正在写信要求解决以下困难的正确解决方案:

我需要以Base64格式对文件进行编码,并且我无法使文件变小,因此,我肯定会遇到OutOfMemory Exception,这就是为什么我使用Streaming方法来解决它。 文件编码后,我已经通过代码和在线工具立即对其进行了解码。 发现解码后的内容有时会在文件末尾丢失2个字节,但并非总是如此。 它确实影响了对文件的进一步处理。

希望有人可以提供帮助,可能是由于一个白痴的错误造成的。 还是谢谢。

这是代码:

FileOutputStream fout = new FileOutputStream(path + ".txt"); //this is for printing out the base64 content FileInputStream fin = new FileInputStream(path); System.out.println("File Size:" + path.getTotalSpace()); ByteArrayOutputStream os = new ByteArrayOutputStream(); Base64OutputStream base64out = new Base64OutputStream(os,Base64.NO_WRAP); byte[] buffer = new byte[3 * 512]; int len = 0; while ((len = fin.read(buffer)) >= 0) { base64out.write(buffer, 0, len); } System.out.println("Encoded Size:" + os.size()); String result = new String(os.toByteArray(), "UTF-8"); fout.write(os.toByteArray()); fout.close(); base64out.close(); os.close(); fin.close(); return result; 

以下是使用Base64OutputStream时的解决方案。 我将在代码后解释其中一些:

这是代码:

 FileOutputStream fout = new FileOutputStream(path + ".txt"); FileInputStream fin = new FileInputStream(path); System.out.println("File Size:" + path.length()); ByteArrayOutputStream os = new ByteArrayOutputStream(); Base64OutputStream base64out = new Base64OutputStream(os,Base64.NO_WRAP); byte[] buffer = new byte[3 * 512]; int len = 0; while ((len = fin.read(buffer)) >= 0) { base64out.write(buffer, 0, len); } System.out.println("Encoded Size:" + os.size()); base64out.flush(); base64out.close();//this did the tricks. Please see explanation. String result = new String(os.toByteArray(), "UTF-8"); fout.write(os.toByteArray()); fout.flush(); fout.close(); os.close(); fin.close(); return result; 

实际上,在使用Dawnkeeper的建议添加了flush()后,我只移动了一行代码。 在处理任何数据之前,这些技巧在base64out.close()中完成。 关闭Base64OutputStream可能会将Base64的Ending Padding写入Output。 我从org.apache.myfaces.trinidad.util.Base64OutputStream close()方法得到了我的想法。 这就是我试过的原因。

在数据处理之前关闭OutputStream似乎很奇怪,但在这种情况下它只会同时关闭Base64OutputStream但不关闭ByteArrayOutputStream。 因此,数据仍然可以从ByteArrayOutputStream中检索。

感谢Dawnkeeper的努力,并希望这个问题可以帮助其他遭受OutOfMemory Exception的人。

在将流用于其他操作之前以及关闭之前,应刷新流:

 FileOutputStream fout = new FileOutputStream(path + ".txt"); //this is for printing out the base64 content FileInputStream fin = new FileInputStream(path); System.out.println("File Size:" + path.length()); // path.getTotalSpace() is the filesystem size ByteArrayOutputStream os = new ByteArrayOutputStream(); Base64OutputStream base64out = new Base64OutputStream(os,Base64.NO_WRAP); byte[] buffer = new byte[3 * 512]; int len = 0; while ((len = fin.read(buffer)) >= 0) { base64out.write(buffer, 0, len); } System.out.println("Encoded Size:" + os.size()); base64out.write(System.lineSeparator().getBytes()); base64out.flush(); // to be sure that everything is in the byte array String result = new String(os.toByteArray(), "UTF-8"); fout.write(os.toByteArray()); fout.flush(); // make sure everything is written fout.close(); base64out.close(); os.close(); fin.close(); System.out.println("new File Size:" + new File(path + ".txt").length()); // prints out the size of the finished file return result;