Base64 按块编码文件

Base64 encode file by chunks

我想将一个文件分成多个块(在本例中,尝试使用 300 的长度)并对它进行 base64 编码,因为将整个文件加载到内存时会在 base64 编码时产生负数组异常。我尝试使用以下代码:

int offset = 0;
bis = new BufferedInputStream(new FileInputStream(f));
while(offset + 300 <= f.length()){
    byte[] temp = new byte[300];
    bis.skip(offset);
    bis.read(temp, 0, 300);
    offset += 300;
    System.out.println(Base64.encode(temp));
}
if(offset < f.length()){
    byte[] temp = new byte[(int) f.length() - offset];
    bis.skip(offset);
    bis.read(temp, 0, temp.length);
    System.out.println(Base64.encode(temp));
}

起初它似乎可以正常工作,但是,有一次它切换到只打印 "AAAAAAAAA" 并用它填满整个控制台,新文件在解码时损坏。可能导致此错误的原因是什么?

skip() "Skips over and discards n bytes of data from the input stream" 和 read() returns "the number of bytes read".

因此,您读取了一些字节,跳过了一些字节,再读取了一些,跳过了,....最终到达 EOF,此时 read() returns -1,但是您忽略了它并且使用包含全 0 的 temp 的内容,然后将其编码为全 A。

您的代码应该是:

try (InputStream in = new BufferedInputStream(new FileInputStream(f))) {
    int len;
    byte[] temp = new byte[300];
    while ((len = in.read(temp)) > 0)
        System.out.println(Base64.encode(temp, 0, len));
}

此代码重用了在循环之前分配的单个缓冲区,因此与您的代码相比,它引起的垃圾回收也少得多。

如果 Base64.encode 没有 3 参数版本,请执行此操作:

try (InputStream in = new BufferedInputStream(new FileInputStream(f))) {
    int len;
    byte[] temp = new byte[300];
    while ((len = in.read(temp)) > 0) {
        byte[] data;
        if (len == temp.length)
            data = temp;
        else {
            data = new byte[len];
            System.arraycopy(temp, 0, data, 0, len);
        }
        System.out.println(Base64.encode(data));
    }
}