Android File To Base64 using streaming sometimes missed 2 bytes

前端 未结 2 705
暖寄归人
暖寄归人 2020-12-20 19:32

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

相关标签:
2条回答
  • 2020-12-20 20:08

    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.

    0 讨论(0)
  • 2020-12-20 20:17

    Your streams should be flushed before using them for other operations and before closing them:

    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;
    
    0 讨论(0)
提交回复
热议问题