无法处理大小超过65535个字符的字符串文字。编译器抛出IllegalArgumentException

时间:2017-02-12 18:54:10

标签: java scala jvm base64 string-literals

我正在尝试解码Scala中的Base64编码图像。字符串文字长度超过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中处理长字符串文字可能是一个很好的解决方法。

2 个答案:

答案 0 :(得分: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

在scala中,您可以使用内置scala.io.Source类:

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

答案 1 :(得分:0)

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

相关问题