我想将一个文件分成多个 block (在本例中,尝试长度为 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()
“跳过并丢弃输入流中的 n 个字节的数据”,read()
返回“读取的字节数”。
因此,您读取了一些字节,跳过了一些字节,又读取了一些,跳过,....最终到达 EOF,此时 read()
返回 -1,但您忽略了它并使用temp
的内容,其中包含全 0,然后编码为全 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));
}
}
关于java - Base64 按 block 编码文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32001185/