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

yur*_*ura 19 java scala inputstream streamreader

例如,我有以下代码

Source.fromFile(new File( path), "UTF-8").getLines()
Run Code Online (Sandbox Code Playgroud)

它抛出异常

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)
Run Code Online (Sandbox Code Playgroud)

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

Joa*_*uer 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);
Run Code Online (Sandbox Code Playgroud)

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

  • @Thilo:如果你坚持使用Java 6,那么Guava提供了[Charsets`类](http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Charsets .html)做同样的事情. (5认同)
  • +1用于向我介绍StandardCharset.我已经这么久了.不再有`catch(UnsupportedEncodingException e){//从不发生}` (3认同)

Dan*_*ral 13

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

Source.fromFile(new File( path), "latin1").getLines()
Run Code Online (Sandbox Code Playgroud)