在作項目的時候遇到須要將文件轉爲base64編碼,並存儲在文件中。程序員
在將文件轉爲base64編碼是會將文件讀入內存,進行base64編碼,輸出到文件中。代碼入下:編碼
1spa 2code 3內存 4ci 5文檔 6it 7base64 8table 9 10 |
FileInputStream stream = new FileInputStream( "D:\\桌面\\程序員-第4版.pdf" ); ByteArrayOutputStream out = new ByteArrayOutputStream(1024); byte [] b = new byte [1024]; int n; while ((n = stream.read(b)) != -1) { out .write(b, 0, n); } stream.close(); out .close(); System. out .println( new String(Base64.encodeBase64( out .toByteArray()))); |
可是大文件在進行base64編碼的時候就會遇到OOM(OOM爲out of memory的簡稱,稱之爲內存溢出)。
產生OOM的緣由:
- 文件太大,超出了內存
- 文件能夠正常讀入內存,因爲base64編碼後的文件比原來的文件大1/3,在編碼的過程當中超出內存
因爲3個常規字符能夠轉換爲4個base64編碼字符,因此使用3的公倍數做爲緩衝區大小。
因此在對大文件進行base64編碼時能夠採用分段編碼,進行輸出。代碼入下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
//使用分段上傳的讀取文件的方式將大文件轉換爲base64編碼數據 官網 www.1b23.com ByteArrayOutputStream os1 = new ByteArrayOutputStream(); InputStream file1 = new FileInputStream( "D:\\桌面\\程序員-第4版.pdf" ); byte [] byteBuf = new byte [3 * 1024 * 1024]; byte [] base64ByteBuf; int count1; //每次從文件中讀取到的有效字節數 while ((count1 = file1.read(byteBuf)) != -1) { if (count1 != byteBuf.length) { //若是有效字節數不爲3*1000,則說明文件已經讀到尾了,不夠填充滿byteBuf了 byte [] copy = Arrays.copyOf(byteBuf, count1); //從byteBuf中截取包含有效字節數的字節段 base64ByteBuf = Base64.encodeBase64(copy); //對有效字節段進行編碼 } else { base64ByteBuf = Base64.encodeBase64(byteBuf); } os1.write(base64ByteBuf, 0, base64ByteBuf.length); os1.flush(); } file1.close(); System. out .println(os1.toString()); |
以上代碼是將編碼後的數據輸出至控制檯。其實最好是將文件分段進行編碼,分段輸出,這樣無論文件多大,均可以進行編碼,而且不會OOM。如下是將文件輸出至txt文檔中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
ByteArrayOutputStream os1 = new ByteArrayOutputStream(); InputStream file1 = new FileInputStream( "D:\\桌面\\程序員-第4版.pdf" ); byte [] byteBuf = new byte [3 * 1024 * 1024]; byte [] base64ByteBuf; int count1; //每次從文件中讀取到的有效字節數 File file = new File( "D:\\1.txt" ); while ((count1 = file1.read(byteBuf)) != -1) { if (count1 != byteBuf.length) { //若是有效字節數不爲3*1000,則說明文件已經讀到尾了,不夠填充滿byteBuf了 byte [] copy = Arrays.copyOf(byteBuf, count1); //從byteBuf中截取包含有效字節數的字節段 base64ByteBuf = Base64.encodeBase64(copy); //對有效字節段進行編碼 } else { base64ByteBuf = Base64.encodeBase64(byteBuf); } FileUtils.writeByteArrayToFile(file, base64ByteBuf, true ); // 將轉換後的數據寫入文件中,該方法會自動建立文件 os1.flush(); } file1.close(); |