2009-11-18 92 views
17

我使用Scala的2.8.0和嘗試讀取管道分隔文件中像下面剪斷代碼:如何解決Scala 2.8.0中的java.nio.charset.UnmappableCharacterException?

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

這裏的錯誤:在線程「主要」的java.nio.charset中

例外。 UnmappableCharacterException:輸入長度= 1 at 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) at java.io.InputStreamReader.read(InputStreamReader.java:167)(BufferedReader.java:136) at java.io.BufferedReader.read(BufferedReader.java:157) at scala.io.BufferedSource $$ anonfun $ 1 $$ anonfun $ apply $ 1。應用(BufferedSource.scala:29) at scala.io.BufferedSource $$ anonfun $ 1 $$ anonfun $ apply $ 1.apply(BufferedSource.scala:29) at scala.io.Codec.wrap(Codec.scala:65)在scala.io.BufferedSource $ anonfun $ 1.apply(BufferedSource.scala:29) $ Inerator(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 $ 20.hasNext(Iterator.scala:320) at scala.io.Source.hasNext(Source。 Scala:209) at scala.collection.Iterator $ class.foreach(Iterator.scala:534) at scala.io.Source.foreach(Source.scala:143) ... at infillreports.Main $ .main (Main.scala:8)infillreports.Main.main(Main.scala) Java結果 :1

回答

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

你簡直太棒了!非常感謝你。 – 2009-11-19 16:06:49

+0

我希望您能花時間瞭解爲什麼在這裏添加「UTF-8」是必要的,以及它如何改變從輸入流中讀取字符的行爲。如果您沒有得到它,請在此處詳細說明您的問題,或者詢問有關字節,字符和字符編碼的新問題。 – seh 2009-11-25 01:55:21

+1

在scala 2.12.3中,你應該寫 Source.fromFile(fileName)(Codec(「utf-8」)) – 2017-11-18 10:25:28

7

我這個同樣的問題掙扎,這個答案幫助了我。我想就「爲什麼這個作品」對seh的評論延伸。答案應該在方法簽名上:

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

它需要一個implict codec參數。然而,在這個例子中,提供了一個字符串,而不是編解碼器。第二個轉換正在發生幕後: 類的護理對象編解碼器定義了一個從字符串申請方法:

def apply(encoding: String): Codec 

所以編譯器做了一些爲我們工作: VAL線= Source.fromFile( someFile)(編解碼器(「UTF-8」))

由於編解碼器是隱含的,如果你調用此方法多次,你也可以在你打電話的範圍之內創建一個編解碼器對象:

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

我希望我有那個r ight(我仍然是斯卡拉n00b,抓住它 - 隨時糾正需要)

+1

實際上,由於'Codec.apply'不是一個隱式轉換,所以編譯器沒有理由靜靜地叫它。實際上它是在這裏調用的Codec.string2codec(因爲它**是從'String'到'Codec'的隱式轉換) – 2016-07-27 08:03:00

4

要添加到丹尼爾C.索布拉爾的回答,你也可以嘗試這樣的事:

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

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

這可能是一個更通用的解決方案:

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

與兩個設置,就可以避免在文件中的格式不正確的數據。

+0

嗨,我想試試你的解決方案,因爲接受的答案沒有解決我的問題問題。但它不會編譯,因爲編譯器無法識別值CodingErrorAction.REPLACE。我已經導入scala.io._,我缺少哪個命名空間? – rumtscho 2014-12-02 09:11:38

+0

您缺少'java.nio.charset.CodingErrorAction' – 2015-04-26 05:33:12

相關問題