如何在Java / Scala中跳过流中的无效字符?
例如,我有以下代码
Source.fromFile(new File( path), "UTF-8").getLines()
它抛出exception
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)
我不在乎是否有些行没有被读取,但是如何跳过无效的字符并继续读取行?
您可以通过调用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")
(或使用Guava中 的Charsets
类 )。
好吧,如果它不是UTF-8,那就是别的了。 诀窍是找出其他东西是什么,但如果您想要的只是避免错误,您可以使用没有无效代码的编码,例如latin1
:
Source.fromFile(new File( path), "latin1").getLines()
我有一个类似的问题,Scala的内置编解码器之一为我做了诀窍:
Source.fromFile(new File(path))(Codec.ISO8859).getLines()
如果你想避免使用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) } } }