2011-09-02 48 views
19

,比如我有下面的代码如何在Java/Scala中忽略流中的无效字符?

Source.fromFile(new File(path), "UTF-8").getLines() 

,并抛出异常

Exception in thread "main" java.nio.charset.MalformedInputException: Input length = 1 
    at java.nio.charset.CoderResult.throwException(CoderResult.java:260) 
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:319) 

我不在乎,如果某些行不读,而是如何跳过无效字符,并继续念台词?

回答

32

您可以通过调用CharsetDecoder.onMalformedInput来影响字符集解码处理无效输入的方式。

通常您不会直接看到CharsetDecoder对象,因为它会在幕后为您创建。因此,如果您需要访问它,则需要使用API​​,以便您直接指定CharsetDecoder(而不仅仅是编码名称或Charset)。

这种API最基本的例子是InputStreamReader

InputStream in = ...; 
CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); 
decoder.onMalformedInput(CodingErrorAction.IGNORE); 
Reader reader = new InputStreamReader(in, decoder); 

请注意,此代码使用了Java 7类StandardCharsets,对于早期版本,你可以简单地用Charset.forName("UTF-8")替换它(或使用the Charsets classGuava) 。

+3

+1将我介绍给StandardCharset。我想这么久。没有更多的catch(UnsupportedEncodingException e){//永远不会发生}' – Thilo

+5

@Thilo:如果你坚持使用Java 6,那么Guava提供[Charsets'类](http://guava-libraries.googlecode.com /svn/trunk/javadoc/com/google/common/base/Charsets.html)执行相同的操作。我实际上是 –

+0

。谢谢;-) – Thilo

13

那么,如果它不是UTF-8,那是别的。诀窍是找出什么别的东西,但如果你想要的是避免这些错误,你可以使用一个编码不具有​​无效代码,如latin1

Source.fromFile(new File(path), "latin1").getLines() 
+1

这个解决方案对我来说真的很有用! –

1

我有一个类似的问题和Scala的内置编解码器之一的伎俩对我来说:

Source.fromFile(new File(path))(Codec.ISO8859).getLines() 
+0

哇,我不知道为什么这个工作,但你救了我的傍晚! – habitats

0

如果你想避免使用Scala的无效字符,我发现这个工作对我来说。

import java.nio.charset.CodingErrorAction 
import scala.io._ 

object HelloWorld { 

    def main(args: Array[String]) = { 
    implicit val codec = Codec("UTF-8") 

    codec.onMalformedInput(CodingErrorAction.REPLACE) 
    codec.onUnmappableCharacter(CodingErrorAction.REPLACE) 

    val dataSource = Source.fromURL("https://www.foo.com") 

    for (line <- dataSource.getLines) { 

     println(line) 
    } 
    } 
}