Как устранить исключение java.nio.charset.UnmappableCharacterException в Scala 2.8.0? - PullRequest
17 голосов
/ 18 ноября 2009

Я использую 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: длина ввода = 1 в java.nio.charset.CoderResult.throwException (CoderResult.java:261) at sun.nio.cs.StreamDecoder.implRead (StreamDecoder.java:319) at sun.nio.cs.StreamDecoder.read (StreamDecoder.java:158) в java.io.InputStreamReader.read (InputStreamReader.java:167) at java.io.BufferedReader.fill (BufferedReader.java:136) 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 $ apply $ 1.apply (BufferedSource.scala: 29) на scala.io.Codec.wrap (Codec.scala: 65) at scala.io.BufferedSource $$ anonfun $ 1.apply (BufferedSource.scala: 29) at scala.io.BufferedSource $$ anonfun $ 1.apply (BufferedSource.scala: 29) на scala.collection.Iterator $$ anon $ 14.next (Iterator.scala: 149) на scala.collection.Iterator $$ anon $ 2.next (Iterator.scala: 745) на scala.collection.Iterator $$ anon $ 2.head (Iterator.scala: 732) на scala.collection.Iterator $$ anon $ 24.hasNext (Iterator.scala: 405) на scala.collection.Iterator $$ anon $ 20.hasNext (Iterator.scala: 320) на scala.io.Source.hasNext (Source.scala: 209) в scala.collection.Iterator $ class.foreach (Iterator.scala: 534) на scala.io.Source.foreach (Source.scala: 143) ... на infillreports.Main $ .main (Main.scala: 8) в infillreports.Main.main (Main.scala) Результат Java: 1

Ответы [ 4 ]

24 голосов
/ 18 ноября 2009
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)
    }
  }
}
7 голосов
/ 21 мая 2011

Я боролся с этой же проблемой, и этот ответ помог мне. Я хотел бы расширить комментарий seh относительно «почему это работает». Ответ должен лежать на подписи метода:

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

Требуется параметр кодека импликта. Тем не менее, в примере указана строка, а не кодек. Второй перевод происходит за кулисами: Сопутствующий объект класса Codec определяет метод apply из String:

def apply(encoding: String): Codec

так что компилятор сделал для нас некоторую работу: val lines = Source.fromFile (someFile) (Кодек ("UTF-8"))

Учитывая, что кодек неявный, если вы вызываете этот метод несколько раз, вы также можете создать объект кодека в области своего вызова:

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

Надеюсь, я понял это правильно (я все еще Scala n00b, но я могу справиться с этим, если нужно)

4 голосов
/ 14 февраля 2012

Чтобы добавить ответ Даниэля С. Собрала, вы также можете попробовать что-то вроде этого:

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

for(p <- products){
        println("product :" + p);
}
1 голос
/ 04 марта 2014

Возможно, это более общее решение:

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

с двумя настройками вы можете избежать искаженных данных в файле.

...