gpt4 book ai didi

用于流的 Java 缓冲 base64 编码器

转载 作者:搜寻专家 更新时间:2023-11-01 01:41:04 24 4
gpt4 key购买 nike

我有很多 PDF 文件,需要使用 base64 对其内容进行编码。我有一个 Akka 应用程序,它以流的形式获取文件并分发给许多工作人员以对这些文件进行编码并为每个文件返回字符串 base64。我得到了一个基本的编码解决方案:

    org.apache.commons.codec.binary.Base64InputStream;
...
Base64InputStream b64IStream = null;
InputStreamReader reader = null;
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
try {
b64IStream = new Base64InputStream(input, true);
reader = new InputStreamReader(b64IStream);
br = new BufferedReader(reader);
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
} finally {
if (b64IStream != null) {
b64IStream.close();
}
if (reader != null) {
reader.close();
}
if (br != null) {
br.close();
}
}

它有效,但我想知道使用缓冲区编码文件的最佳方法是什么,以及是否有更快的替代方法。

我测试了其他一些方法,例如:

  • Base64.getEncoder
  • sun.misc.BASE64Encoder
  • Base64.encodeBase64
  • javax.xml.bind.DatatypeConverter.printBase64
  • com.google.guava.BaseEncoding.base64

它们速度更快,但需要整个文件,对吗?另外,我不想在编码 1 个 PDF 文件时阻塞其他线程。

任何输入都非常有用。谢谢!

最佳答案

关于 Base64 的有趣事实:它需要三个字节,并将它们转换为四个字母。这意味着如果您读取可被三整除的 block 中的二进制数据,您可以将这些 block 提供给 任何 Base64 编码器,它会以与将整个文件提供给它相同的方式对其进行编码.

现在,如果您希望输出流只是一长行 Base64 数据——这是完全合法的——那么您需要做的就是:

private static final int BUFFER_SIZE = 3 * 1024;

try ( BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE); ) {
Base64.Encoder encoder = Base64.getEncoder();
StringBuilder result = new StringBuilder();
byte[] chunk = new byte[BUFFER_SIZE];
int len = 0;
while ( (len = in.read(chunk)) == BUFFER_SIZE ) {
result.append( encoder.encodeToString(chunk) );
}
if ( len > 0 ) {
chunk = Arrays.copyOf(chunk,len);
result.append( encoder.encodeToString(chunk) );
}
}

这意味着只有最后一个 block 的长度不能被三整除,因此将包含填充字符。

上面的示例是使用 Java 8 Base64 的,但您实际上可以使用任何采用任意长度的字节数组并返回该字节数组的 ba​​se64 字符串的编码器。

这意味着您可以随意调整缓冲区大小。

但是,如果您希望输出与 MIME 兼容,则需要将输出分成几行。在这种情况下,我会将上例中的 block 大小设置为乘以 4/3 后的整数行数。例如,如果你想每行有 64 个字符,则每行编码 64/4 * 3,即 48 个字节。如果你编码 48 个字节,你会得到一行。如果您编码 480 个字节,您将得到 10 整行。

因此将上面的 BUFFER_SIZE 修改为 4800 之类的值。使用 Base64.getMimeEncoder(64,new byte[] { 13, 10}) 代替 Base64.getEncoder()。然后,当它编码时,你将从每个 block 中获得 100 行全尺寸行,最后一个除外。您可能需要将 result.append("\r\n") 添加到 while 循环。

关于用于流的 Java 缓冲 base64 编码器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39082816/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com