我一直在尝试解决Java程序中的内存问题,在Java程序中,我们将整个文件加载到内存中,对它进行base64编码,然后将其用作发布请求中的表单参数。由于文件太大,这是导致OOME的原因。
我正在研究一种解决方案,其中我能够通过base64编码器将文件流式传输到Http Post请求的请求主体中。我在所有流行的编码库(Guava,java.util.Base64,android.util.Base64和org.apache.batik.util)中注意到的常见模式之一是if该库支持使用流,编码始终通过OutputStream完成,而解码始终通过InputStream完成。
我在寻找/确定这些决定背后的原因时遇到了麻烦。鉴于这么多流行且编写良好的库都符合此api设计,因此我认为这是有原因的。使这些解码器之一适应成为InputStream或接受InputStream似乎并不困难,但是我想知道这些编码器是采用这种方式设计的,这是否有合理的架构原因。
为什么普通库通过OuputStream进行Base64编码,而通过InputStream进行Base64解码?
支持我的主张的示例:
java.util.Base64
- Base64.Decoder.wrap(InputStream stream)
- Base64.Encoder.wrap(OutputStream stream)
android.util.Base64
- Base64InputStream // An InputStream that does Base64 decoding on the data read through it.
- Base64OutputStream // An OutputStream that does Base64 encoding
google.common.io.BaseEncoding
- decodingStream(Reader reader)
- encodingStream(Writer writer)
org.apache.batik.util
- Base64DecodeStream implements InputStream
- Base64EncodeStream implements OutputStream
嗯,是的,您可以将其反转,但这是最有意义的。 Base64用于使binary data(由应用程序生成或操作)与基于文本的外部环境兼容。 因此外部总是需要base 64编码的部分,而内部总是需要解码的部分。]] >> 如果要将二进制数据导出到外部,自然会使用输出流。如果该数据需要使用base 64进行编码,请确保将数据发送到编码为base 64的输出流。
如果要从外部导入二进制数据,则可以使用输入流。如果该数据是使用base 64编码的,则首先需要对其进行解码,因此在将其视为二进制流之前,请确保对其进行解码。
让我们创建一些图片。假设您有一个在文本界面上运行但在二进制数据上运行的应用程序。
然后您得到:
{APPLICATION} <- (binary data decoding) <- (base64 decoding) <- (file input stream) <- [BASE 64 ENCODED FILE]
为此,您自然使用输入流。
所以让我们看一下输出:
{APPLICATION} -> (binary data encoding) -> (base64 encoding) -> (file output stream) -> [BASE 64 ENCODED FILE]
为此,您自然使用输出流。
[将跟随Java示例]