2017-02-12 5 views
3

Я пытаюсь декодировать изображение с кодировкой Base64 в Scala. Строковый литерал имеет длину более 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

Если вы можете читать по четыре байта за раз, это будет соответствовать точно трем байтам после декодирования. Объедините их вместе, и вы получите тот же результат.