2009-11-18 8 views
17

estoy usando Scala 2.8.0 y tratando de leer el archivo delimitado pipa como en el código cortado con tijeras a continuación:Cómo resolver java.nio.charset.UnmappableCharacterException en 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) 
    } 
    } 
} 

Aquí está el error:

Excepción en hilo java.nio.charset "principal". UnmappableCharacterException: longitud de entrada = 1 en java.nio.charset.CoderResult.throwException (CoderResult.java:261) en sun.nio.cs.StreamDecoder.implRead (StreamDecoder.java:319) en sun.nio.cs. StreamDecoder.read (StreamDecoder.java:158) en java.io.InputStreamReader.read (InputStreamReader.java:167) en java.io.BufferedReader.fill (BufferedReader.java:136) en java.io.BufferedReader.read (BufferedReader.java:157) en scala.io.BufferedSource $$ anonfun $ 1 $$ anonfun $ apply $ 1. aplicar (BufferedSource.scala: 29) en scala.io.BufferedSource $$ anonfun $ 1 $$ anonfun $ apply $ 1.apply (BufferedSource.scala: 29) en scala.io.Codec.wrap (Codec.scala: 65) en scala.io.BufferedSource $$ anonfun $ 1.apply (BufferedSource.scala: 29) en scala.io.BufferedSource $$ anonfun $ 1.aplicación (BufferedSource.scala: 29) en scala.collection.Iterator $$ anon $ 14.next (Iterator.scala: 149) at scala.collection.Iterator $$ anon $ 2.next (Iterator.scala: 745) at scala.collection.Iterator $$ anon $ 2.head (Iterator.scala: 732) at scala.collection.Iterator $$ anon $ 24.hasNext (Iterator.scala: 405) en scala.collection.Iterator $$ anon $ 20.hasNext (Iterator.scala: 320) en scala.io.Source.hasNext (Fuente. scala: 209) en scala.collection.Iterator $ class.foreach (Iterator.scala: 534) en scala.io.Source.foreach (Source.scala: 143) ... en infillreports.Main $ .main (Main.scala: 8) en infillreports.Main.main (Main.scala) Java Resultado: 1

Respuesta

24
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) 
    } 
    } 
} 
+1

¡Eres simplemente IMPRESIONANTE! Muchas gracias. –

+0

Espero que se tome el tiempo para comprender por qué era necesario agregar "UTF-8" aquí, y cómo cambió el comportamiento de la lectura de los caracteres del flujo de entrada. Si no lo obtiene, elabore su pregunta aquí o formule una nueva pregunta sobre los bytes, los caracteres y las codificaciones de los personajes. – seh

+1

En scala 2.12.3 debe escribir Source.fromFile (fileName) (Codec ("utf-8")) –

7

he tenido problemas con este mismo tema y esta respuesta me ayudó. Quería extender el comentario de se sobre el 'por qué esto funciona'. La respuesta debe estar en la firma del método:

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

Toma un parámetro de códec implícito. Sin embargo, en el ejemplo, se proporciona una cadena, no un códec. Una segunda traducción se lleva a cabo detrás de las escenas: El objeto acompañante de la clase Codec define un método de aplicar a partir de la secuencia:

def apply(encoding: String): Codec 

lo que el compilador ha realizado un trabajo para nosotros: líneas val = Source.fromFile (somefile) (Codec ("UTF-8"))

Dado que Codec es implícita, si está llamando a este método varias veces, también puede crear un objeto Codec en el ámbito de su llamada:

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

Espero tener ese r ight (sigo siendo un Scala n00b, pongo mis manos en ello - no dude en corregir donde sea necesario)

+1

En realidad, dado que 'Codec.apply' no es una conversión implícita, no hay ninguna razón para que el compilador silenciosamente llámalo. De hecho, es 'Codec.string2codec' que se llama aquí (ya que ** es ** una conversión implícita de' String' a 'Codec') –

4

Agregar a Daniel C.La respuesta de Sobral, también puedes intentar algo como esto:

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

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

Esto puede ser una solución más genérica:

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

con las dos configuraciones, puede evitar los datos con formato incorrecto en el archivo.

+0

Hola, quería probar tu solución porque la respuesta aceptada no solucionó mi problema. problema. Pero no compila, ya que el compilador no reconoce el valor CodingErrorAction.REPLACE. He importado scala.io._, ¿qué espacio de nombres me falta? – rumtscho

+0

Te has perdido 'java.nio.charset.CodingErrorAction' –

Cuestiones relacionadas