首页 > 解决方案 > Base64编码到解码文件转换问题

问题描述

我正在处理非常大的文件(> 2Gig)。每个输入文件都是 Base64 编码的,我在解码后输出到新文件。根据缓冲区大小 (LARGE_BUF) 和给定的输入文件,我的输入到输出转换要么工作正常,要么丢失一个或多个字节,要么在 outputStream.write 行抛出异常(IllegalArgumentException: Last unit does not have enough位)。这是代码片段(无法剪切和粘贴,所以我并不完美):

.
.

final int LARGE_BUF = 1024;
byte[] inBuf = new byte[LARGE_BUF];

try(InputStream inputStream = new FileInputStream(inFile); OutputStream outStream new new FileOutputStream(outFile)) {

   for(int len; (len = inputStream.read(inBuf)) > 0); ) {
      String out = new String(inBuf, 0, len);
      outStream.write(Base64.getMimeDecoder().decode(out.getBytes()));
   }
}

例如,对于我的示例输入文件,如果 LARGE_BUF 为 1024,则输出文件太小了 4 个字节,如果 2*1024,我得到上面提到的异常,如果 7*1024,它可以正常工作。感谢任何想法。谢谢你。

标签: java

解决方案


首先,您将字节转换为字符串,然后立即转换回字节。因此,完全删除 String 的使用。

其次,base64编码将每个三个字节的序列变成了四个字节,所以在解码的时候,需要四个字节才能正确解码三个字节的原始数据。为每个任意读取的字节序列创建一个新的解码器是不安全的,它的长度可能是也可能不是四的精确倍数。

最后,Base64.Decoder 有一个wrap(InputStream) 方法,这使得这变得相当容易:

try (InputStream inputStream = Base64.getDecoder().wrap(
    new BufferedInputStream(
        Files.newInputStream(Paths.get(inFile))))) {

    Files.copy(inputStream, Paths.get(outFile));
}

推荐阅读