有趣的是,我在這裏做了一些測試,當您使用InputStreamReader
讀取Base64InputStream
時,它確實會拋出異常,無論流的來源如何,但是當您將它作爲二進制流讀取時,它的工作完美無瑕。正如Trashgod所提到的,Base64編碼被構造。 InputStreamReader
實際上應該再次調用flush()
Base64InputStream
以查看它是否不返回任何數據。
我沒有看到其他解決此問題的方法,而不是實施您自己的
Base64InputStreamReader
或
Base64Reader
。 這實際上是一個錯誤,請參閱Keith的答案。
作爲一種解決方法,您也可以將其存儲在數據庫中的BLOB而不是CLOB中,並使用PreparedStatement#setBinaryStream()
代替。它是否存儲爲二進制數據並不重要。無論如何,您不希望將這樣大的Base64數據轉換爲可索引或可搜索的。
更新:因爲這不是一個選項,並具有阿帕奇共享編解碼器傢伙修復Base64InputStream
錯誤,我repored作爲CODEC-101可能需要一些時間,你可以考慮使用其他第三方的Base64 API。我找到了一個here(公有領域,所以你可以做任何你想要的東西,甚至放置在你自己的包中),我已經在這裏測試過了,它工作正常。
InputStream base64 = new Base64.InputStream(input, Base64.ENCODE);
更新2:公地編解碼器傢伙fixed它很快。
Index: src/java/org/apache/commons/codec/binary/Base64InputStream.java
===================================================================
--- src/java/org/apache/commons/codec/binary/Base64InputStream.java (revision 950817)
+++ src/java/org/apache/commons/codec/binary/Base64InputStream.java (working copy)
@@ -145,21 +145,41 @@
} else if (len == 0) {
return 0;
} else {
- if (!base64.hasData()) {
- byte[] buf = new byte[doEncode ? 4096 : 8192];
- int c = in.read(buf);
- // A little optimization to avoid System.arraycopy()
- // when possible.
- if (c > 0 && b.length == len) {
- base64.setInitialBuffer(b, offset, len);
+ int readLen = 0;
+ /*
+ Rationale for while-loop on (readLen == 0):
+ -----
+ Base64.readResults() usually returns > 0 or EOF (-1). In the
+ rare case where it returns 0, we just keep trying.
+
+ This is essentially an undocumented contract for InputStream
+ implementors that want their code to work properly with
+ java.io.InputStreamReader, since the latter hates it when
+ InputStream.read(byte[]) returns a zero. Unfortunately our
+ readResults() call must return 0 if a large amount of the data
+ being decoded was non-base64, so this while-loop enables proper
+ interop with InputStreamReader for that scenario.
+ -----
+ This is a fix for CODEC-101
+ */
+ while (readLen == 0) {
+ if (!base64.hasData()) {
+ byte[] buf = new byte[doEncode ? 4096 : 8192];
+ int c = in.read(buf);
+ // A little optimization to avoid System.arraycopy()
+ // when possible.
+ if (c > 0 && b.length == len) {
+ base64.setInitialBuffer(b, offset, len);
+ }
+ if (doEncode) {
+ base64.encode(buf, 0, c);
+ } else {
+ base64.decode(buf, 0, c);
+ }
}
- if (doEncode) {
- base64.encode(buf, 0, c);
- } else {
- base64.decode(buf, 0, c);
- }
+ readLen = base64.readResults(b, offset, len);
}
- return base64.readResults(b, offset, len);
+ return readLen;
}
}
我在這裏試過,它工作正常。
是的,你是對的。這是Base64InputStream中的一個錯誤。對於確認這一點的測試用例+1。 – BalusC 2010-05-30 03:46:32
報告順便說一句:https://issues.apache.org/jira/browse/CODEC-101這就是說,我仍然想知道我的測試文件確實是3字節長的倍數的巧合:o) – BalusC 2010-05-30 04:08:48
哇,謝謝你的確認,我必須說我驚訝於我發現了這樣的錯誤(無意中)。 – karoberts 2010-05-30 05:27:27