如何解决Scala 2.8.0中的java.nio.charset.UnmappableCharacterException?

我正在使用Scala 2.8.0并尝试读取管道分隔文件,如下面的代码剪切:

object Main {
  def main(args: Array[String]) :Unit = {
    if (args.length > 0) {
      val lines = scala.io.Source.fromPath("QUICK!LRU-2009-11-15.psv")
     for (line <-lines)
       print(line)
    }
  }
}

这是错误:

线程“main”中的异常java.nio.charset.UnmappableCharacterException:在sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:)的java.nio.charset.CoderResult.throwException(CoderResult.java:261)输入长度= 1 . 319)at.nio.cs.StreamDecoder.read(StreamDecoder.java:158)at java.io.InputStreamReader.read(InputStreamReader.java:167)at java.io.BufferedReader.fill(BufferedReader.java:136)at at java.io.BufferedReader.read(BufferedReader.java:157)at scala.io.BufferedSource $$ anonfun $ 1 $$ anonfun $ apply $ 1.apply(BufferedSource.scala:29)at scala.io.BufferedSource $$ anonfun $ 1 $ $ anonfun $在scala.io.Codec.wrap(Codec.scala:65)的scala.io.BufferedSource $$ anonfun $ 1.apply(BufferedSource.scala:29)scala上应用$ 1.apply(BufferedSource.scala:29) .io.BufferedSource $$ anonfun $ 1.apply(BufferedSource.scala:29)at scala.collection.Iterator $$ anon $ 14.next(Iterator.scala:149)at scala.collection.Iterator $$ anon $ 2.next(Iterator .scala:745)scala.collection.Iterator $$ anon $ 2.head(Iterator.scala:732)at scala.col lection.Iterator $$ anon $ 24.hasNext(Iterator.scala:405)at scala.collection.Iterator $$ anon $ 20.hasNext(Iterator.scala:320)at scala.io.Source.hasNext(Source.scala:209) at scala.collection.Iterator $ class.foreach(Iterator.scala:534)at scala.io.Source.foreach(Source.scala:143)... at infillreports.Main $ .main(Main.scala:8)at at infillreports.Main.main(Main.scala)Java结果:1

回答(4)

2 years ago

object Main {
  def main(args: Array[String]) :Unit = {
    if (args.length > 0) {
      val lines = scala.io.Source.fromPath("QUICK!LRU-2009-11-15.psv")("UTF-8")
      for (line <-lines)
        print(line)
    }
  }
}

2 years ago

我正在努力解决这个问题,这个答案对我有所帮助 . 我想延伸seh关于'为什么这样有效'的评论 . 答案应该在方法签名上:

def fromFile(file: JFile)(implicit codec: Codec): BufferedSource

它需要一个implict编解码器参数 . 然而,在该示例中,提供了字符串,而不是编解码器 . 第二个翻译发生在幕后:Codec类的伴随对象定义了String中的apply方法:

def apply(encoding: String): Codec

所以编译器为我们做了一些工作:val lines = Source.fromFile(someFile)(Codec(“UTF-8”))

鉴于Codec是隐式的,如果您多次调用此方法,您还可以在调用范围内创建Codec对象:

implicit val codec = Codec("UTF-8")
val lines = Source.fromFile(someFile)
val moreLines = Source.fromFile(someOtherFile)

我希望我做对了(我仍然是Scala n00b, grab 它 - 随时根据需要纠正)

2 years ago

要添加Daniel C. Sobral的答案,您还可以尝试这样的事情:

val products = Source.fromFile("products.txt")("UTF-8").getLines().toList;

for(p <- products){
        println("product :" + p);
}

2 years ago

这可能是更通用的解决方案:

implicit val codec = Codec("UTF-8")
codec.onMalformedInput(CodingErrorAction.REPLACE)
codec.onUnmappableCharacter(CodingErrorAction.REPLACE)

使用这两个设置,可以避免文件中格式错误的数据 .