2009-11-18 6 views
17

Ich verwende Scala 2.8.0 und versuchen Rohr getrennte Datei wie in Code zu lesen unter snipped:Wie löst man java.nio.charset.UnmappableCharacterException in Scala 2.8.0 auf?

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) 
    } 
    } 
} 

Hier ist der Fehler:

Exception in thread "main" java.nio.charset. UnmappableCharacterException: Eingabelänge = 1 bei java.nio.charset.CoderResult.throwException (CoderResult.java:261) unter sun.nio.cs.StreamDecoder.implRead (StreamDecoder.java:319) bei sun.nio.cs. StreamDecoder.read (StreamDecoder.java:158) bei java.io.InputStreamReader.read (InputStreamReader.java:167) bei java.io.BufferedReader.fill (BufferedReader.java:136) bei java.io.BufferedReader.read (BufferedReader.java:157) bei scala.io.BufferedSource $$ anonfun $ 1 $ $ anonfun $ gelten $ 1. apply (BufferedSource.scala: 29) bei scala.io.BufferedSource $$ anonfun $ 1 $$ anonfun $ anwenden $ 1.apply (BufferedSource.scala: 29) bei scala.io.Codec.wrap (Codec.scala: 65) bei scala.io.BufferedSource $$ anonfun $ 1.apply (BufferedSource.scala: 29) bei scala.io.BufferedSource $$ anonfun $ 1.apply (BufferedSource.scala: 29) bei scala.collection.Iterator $$ anon $ 14.next (Iterator.scala: 149) bei scala.collection.Iterator $$ anon $ 2.next (Iterator.scala: 745) bei scala.collection.Iterator $$ anon $ 2.head (Iterator.scala: 732) bei scala.collection.Iterator $$ anon $ 24.hasNext (Iterator.scala: 405) bei scala.collection.Iterator $$ anon $ 20.hasNext (Iterator.scala: 320) bei scala.io.Source.hasNext (Quelle. scala: 209) bei scala.collection.Iterator $ class.foreach (Iterator.scala: 534) bei scala.io.Source.foreach (Source.scala: 143) ... bei infillreports.Main $ .main (Main.scala: 8) bei infillreports.Main.main (Main.scala) Java Ergebnis: 1

Antwort

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

Sie sind einfach super !!!! Vielen Dank. –

+0

Ich hoffe, Sie werden sich die Zeit nehmen zu verstehen, warum das Hinzufügen von "UTF-8" hier notwendig war und wie es das Verhalten beim Lesen von Zeichen aus dem Eingabestream verändert hat. Wenn Sie es nicht verstehen, sollten Sie Ihre Frage hier beantworten oder eine neue Frage zu Bytes, Zeichen und Zeichenkodierungen stellen. – seh

+1

In Scala 2.12.3 sollten Sie schreiben Source.fromFile (fileName) (Codec ("Utf-8")) –

7

ich mit dem gleichen Problem zu kämpfen hatte und diese Antwort hat mir geholfen. Ich wollte den Kommentar von seh zum "Warum das funktioniert" erweitern. Die Antwort sollte auf der Methodensignatur liegen:

Es dauert ein imcidt Codec-Parameter. Im Beispiel wird jedoch eine Zeichenfolge bereitgestellt, kein Codec. Eine zweite Übersetzung findet hinter den Kulissen: Der Begleiter Objekt der Klasse Codec eine Methode von String anwenden definiert:

def apply(encoding: String): Codec 

so dass der Compiler einige Arbeit für uns getan hat: val Linien = Source.fromFile (somefile) (Codec („UTF-8“))

Da Codec implizit ist, wenn Sie diese Methode mehrmals aufrufen, können Sie auch einen Codec Objekt im Rahmen des Gesprächs erstellen:

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

Ich hoffe, ich habe das r (Ich bin immer noch eine Scala n00b, bekomme meine Griffe dran - fühle mich frei, wo nötig)

+1

Eigentlich, da 'Codec.apply' ist keine implizite Konvertierung, gibt es keinen Grund für den Compiler im Hintergrund nennen. Tatsächlich ist es 'Codec.string2codec', das hier aufgerufen wird (da ** eine implizite Umwandlung von' String' in 'Codec' ist) –

4

Hinzufügen zu Daniel C.Sobral Antwort, können Sie auch so etwas wie dies versuchen:

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

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

Dies vielleicht eine allgemeinere Lösung:

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

mit den beiden Einstellungen, um die fehlerhaften Daten in der Datei zu vermeiden.

+0

Hallo, ich wollte deine Lösung versuchen, weil die angenommene Antwort meine nicht löst Problem. Es kompiliert jedoch nicht, da der Compiler den Wert CodingErrorAction.REPLACE nicht erkennt. Ich habe scala.io._ importiert, welcher Namensraum fehlt mir? – rumtscho

+0

Sie vermissen 'java.nio.charset.CodingErrorAction' –

Verwandte Themen