2017-02-12 138 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

如果您一次可以读取四个字节,那么一旦解码完成,这将对应三个字节。将它们连接在一起,你会得到相同的结果。

相关问题