Ответ 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)
}
}
}
Я использую 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
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)
}
}
}
Я боролся с этой же проблемой, и этот ответ помог мне. Я хотел распространить на комментарий 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, получаю мои ручки на нем - не стесняйтесь исправлять там, где это необходимо)
Чтобы добавить к ответу Даниэля С. Собраля, вы также можете попробовать что-то вроде этого:
val products = Source.fromFile("products.txt")("UTF-8").getLines().toList;
for(p <- products){
println("product :" + p);
}
Это может быть более общее решение:
implicit val codec = Codec("UTF-8")
codec.onMalformedInput(CodingErrorAction.REPLACE)
codec.onUnmappableCharacter(CodingErrorAction.REPLACE)
с двумя настройками, вы можете избежать искаженных данных в файле.