2017-02-12 15 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")) 

コンパイラ例外:このbug 1として

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) 

、私はJVM仕様によると、2バイトのフィールドよりも大きなバイトの長さが合わないことを理解します。網羅的な検索の後、私はこの問題の回避策を見つけることができません。 Java/Scalaの長い文字列リテラルを扱ううえで、すばらしい回避策があります。

+0

なぜ文字列リテラルが必要ですか?あなたはファイルから読むことができませんか? – nmat

+0

アプリケーションサーバーで要求として文字列入力を処理しています。 – Sudhakar

答えて

5

このリテラルはいつか、実際にはコードに埋め込まれるべきではありません。なぜなら、読みやすさの問題があるからです。私はファイル/リソースからロードします。 Commons IO

のJava

これは行うことは本当に簡単です:やや読みにくく、私の意見では

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

、しかし、あなたが本当にあなたもこの開始を行うことができます任意のライブラリを使用したくない場合Scalaで

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

スカラ:Javaの7からビルドインのscala.io.Sourceクラスを使用することができます。

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

+1

Java 1.7に 'Files'クラスがある場合、Commons IOを使用する理由: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

一度に4バイトを読み取ることができる場合、これはデコードされた正確に3バイトに対応します。一緒に連結すると、同じ結果が得られます。

関連する問題