如何在Java / Scala中跳过流中的无效字符?

时间:2011-09-02 08:29:59

标签: java scala inputstream streamreader

例如我有以下代码

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)

我不在乎是否读取了某些行,但是如何跳过无效的字符并继续读取行?

4 个答案:

答案 0 :(得分:33)

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

通常您将永远不会直接看到CharsetDecoder对象,因为它将在幕后为您创建。因此,如果您需要访问它,则需要使用允许您直接指定CharsetDecoder的API(而不仅仅是编码名称或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 class中的Guava)。

答案 1 :(得分:13)

好吧,如果它不是UTF-8,那就是别的了。诀窍是找出其他东西是什么,但如果你想要的只是避免错误,你可以使用没有无效代码的编码,例如latin1

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

答案 2 :(得分:1)

我有一个类似的问题,Scala的内置编解码器之一为我做了诀窍:

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

答案 3 :(得分: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)
    }
  }
}