2017-02-12 134 views
3

我想解碼Scala中的Base64編碼圖像。字符串文字長度超過65535個字符。每當我嘗試編譯下面的代碼時,編譯器都會給出一個IllegalArgumentException。無法處理大於65535個字符的字符串文字大小。編譯器拋出IllegalArgumentException

Scala代碼:

val data = "/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAA ... " 
val imageByte = Base64.getDecoder.decode(data)   
val byteArray = new ByteArrayInputStream(imageByte)  
val image = ImageIO.read(byteArray)      
ImageIO.write(image, "jpeg", new File("image.jpeg")) 

編譯例外:

Error:scalac: Error:   org.jetbrains.jps.incremental.scala.remote.ServerException 
java.lang.IllegalArgumentException 
at scala.tools.asm.ByteVector.putUTF8(ByteVector.java:213) 
at scala.tools.asm.ClassWriter.newUTF8(ClassWriter.java:1092) 
at scala.tools.asm.ClassWriter.newString(ClassWriter.java:1525) 
at scala.tools.asm.ClassWriter.newConstItem(ClassWriter.java:1042) 
at scala.tools.asm.MethodWriter.visitLdcInsn(MethodWriter.java:1134) 
at scala.tools.nsc.backend.jvm.GenASM$JPlainBuilder.genConstant(GenASM.scala:1582) 
at scala.tools.nsc.backend.jvm.GenASM$JPlainBuilder.scala$tools$nsc$backend$jvm$GenASM$JPlainBuilder$$genInstr$1(GenASM.scala:2296) 
at scala.tools.nsc.backend.jvm.GenASM$JPlainBuilder$$anonfun$genBlock$1$2.apply(GenASM.scala:2227) 
at scala.tools.nsc.backend.jvm.GenASM$JPlainBuilder$$anonfun$genBlock$1$2.apply(GenASM.scala:2213) 
at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33) 
at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:186) 
at scala.tools.nsc.backend.icode.BasicBlocks$BasicBlock.foreach(BasicBlocks.scala:195) 
at scala.tools.nsc.backend.jvm.GenASM$JPlainBuilder.genBlock$1(GenASM.scala:2213) 
at scala.tools.nsc.backend.jvm.GenASM$JPlainBuilder.genBlocks$1(GenASM.scala:2151) 
at scala.tools.nsc.backend.jvm.GenASM$JPlainBuilder.genCode(GenASM.scala:2746) 
at scala.tools.nsc.backend.jvm.GenASM$JPlainBuilder.genMethod(GenASM.scala:1471) 
at scala.tools.nsc.backend.jvm.GenASM$JPlainBuilder.genClass(GenASM.scala:1341) 
at scala.tools.nsc.backend.jvm.GenASM$AsmPhase.emitFor$1(GenASM.scala:198) 
at scala.tools.nsc.backend.jvm.GenASM$AsmPhase.run(GenASM.scala:204) 
at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1501) 
at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1486) 
at scala.tools.nsc.Global$Run.compileSources(Global.scala:1481) 
at scala.tools.nsc.Global$Run.compile(Global.scala:1582) 
at xsbt.CachedCompiler0.run(CompilerInterface.scala:115) 
at xsbt.CachedCompiler0.run(CompilerInterface.scala:94) 
at xsbt.CompilerInterface.run(CompilerInterface.scala:22) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:101) 
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:47) 
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:41) 
at org.jetbrains.jps.incremental.scala.local.IdeaIncrementalCompiler.compile(IdeaIncrementalCompiler.scala:29) 
at org.jetbrains.jps.incremental.scala.local.LocalServer.compile(LocalServer.scala:26) 
at org.jetbrains.jps.incremental.scala.remote.Main$.make(Main.scala:67) 
at org.jetbrains.jps.incremental.scala.remote.Main$.nailMain(Main.scala:24) 
at org.jetbrains.jps.incremental.scala.remote.Main.nailMain(Main.scala) 
at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at com.martiansoftware.nailgun.NGSession.run(NGSession.java:319) 

按本bug,我明白的是,根據JVM規範,字節長度大於2個字節的字段更大將不適合。徹底搜索後,我仍然無法找到解決此問題的解決方法,該問題仍然處於活動狀態。在Java/Scala中處理長字符串文字可能是一個很好的解決方法。

+0

爲什麼你需要有一個字符串文字?你不能從文件中讀取嗎? – nmat

+0

我正在處理字符串輸入作爲應用程序服務器中的請求。 – Sudhakar

回答

5

什麼時候文字是這麼長,它應該不會被嵌入代碼了,因爲可讀性問題。我會從一個文件/資源​​加載它。

的Java

隨着Commons IO這是很容易做到:

String str = IOUtils.toString(this.getClass().getResource("myResource", StandardCharsets.UTF_8); 

在我看來,略少於可讀,但如果你真的不想使用任何庫,你也可以做到這一點出發從Java 7:

String str = new String(Files.readAllBytes(Paths.get("myResource")), StandardCharsets.UTF_8); 

斯卡拉

斯卡拉你可以使用內置的scala.io.Source類:

val testTxtSource = Source.fromFile("myResource") 
val str = testTxtSource.mkString() 
testTxtSource.close() 
+1

爲什麼使用Commons IO,如果Java 1.7有'Files'類:'String s = new String(Files.readAllBytes(Paths.get(「myResource」)),Charset.defaultCharset());' – matoni

+0

@matoni謝謝!我也加了你的方式。 –

+0

我還會提到'scala.io.Source',但是需要使用幾行代碼才能正確使用(處理錯誤和釋放資源)。你可以在這裏閱讀更多:http://stackoverflow.com/questions/4458864/whats-the-right-way-to-use-scala-io-source – stefanobaghino

0

如果您一次可以讀取四個字節,那麼一旦解碼完成,這將對應三個字節。將它們連接在一起,你會得到相同的結果。

相關問題