Подтвердить что ты не робот

Как разрешить java.nio.charset.UnmappableCharacterException в Scala 2.8.0?

Я использую 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)       в java.io.BufferedReader.fill(BufferedReader.java:136)       в 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

4b9b3361

Ответ 1

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

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

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

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

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, получаю мои ручки на нем - не стесняйтесь исправлять там, где это необходимо)

Ответ 3

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

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

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

Ответ 4

Это может быть более общее решение:

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

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