Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
428 views
in Technique[技术] by (71.8m points)

java - Android File To Base64 using streaming sometimes missed 2 bytes

i am writing to ask for the proper solution for solving the following difficulties:

I am required to encode the file in Base64 format, and there is no way for me to make the file small, as a result, i will surely suffered from OutOfMemory Exception, that why i used Streaming approach for solving it. After the file is encoded, i have decoded it immediately by code and also online-tools. The decoded content was found missing 2 bytes at the end of the file sometimes, but not always. It did affected further processing to the file.

Hope someone could help and may be caused by an idiot mistake. Still thanks.

Here is the Code:

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;
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is the solution that works in the case of using Base64OutputStream. I will explain some of them after code:

Here is the Code:

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;

Actually, after using the suggestion from Dawnkeeper by added flush(), i have moved one line of code only. The tricks is did in the base64out.close() before processing any data. As closing the Base64OutputStream might write Ending Padding of Base64 to the Output. I got my idea from org.apache.myfaces.trinidad.util.Base64OutputStream close() method. That's why i tried.

It might seems strange closing the OutputStream before data processing, but it only close Base64OutputStream but not ByteArrayOutputStream at the same time in this case. Therefore, the data could still retrieve from ByteArrayOutputStream.

Thanks Dawnkeeper efforts, and hope this question could helps other suffered in OutOfMemory Exception.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...