如何检测非法的UTF-8字节序列以在java输入流中替换它们?
有问题的文件不在我的控制之下。 大多数字节序列都是有效的UTF-8,它不是ISO-8859-1(或其他编码)。 我想尽我所能提取尽可能多的信息。
该文件包含一些非法字节序列,应替换为替换字符。
这不是一件容易的事,它认为它需要一些关于UTF-8状态机的知识。
Oracle有一个包装器可以满足我的需求:
UTF8ValidationFilter javadoc
是否有类似的东西(商业或免费软件)?
谢谢
-stephan
解:
final BufferedInputStream in = new BufferedInputStream(istream); final CharsetDecoder charsetDecoder = StandardCharsets.UTF_8.newDecoder(); charsetDecoder.onMalformedInput(CodingErrorAction.REPLACE); charsetDecoder.onUnmappableCharacter(CodingErrorAction.REPLACE); final Reader inputReader = new InputStreamReader(in, charsetDecoder);
java.nio.charset.CharsetDecoder做你需要的。 此类为不同类型的错误提供了用户可定义的onMalformedInput()
解码(请参阅onMalformedInput()
和onUnmappableCharacter()
)。
CharsetDecoder
写入一个OutputStream
,您可以使用java.io.PipedOutputStream
将其传递到InputStream
,从而有效地创建一个过滤的InputStream
。
一种方法是读取前几个字节以检查字节顺序标记(如果存在)。 有关BOM的更多信息: http : //en.wikipedia.org/wiki/Byte_order_mark在给定的URL中,您将找到BOM字节的表。 但是,一个问题是,UTF-8不需要在其标题中使用BOM。 解决问题的另一种方法是通过模式识别(每次读取几个字节-8位)。 无论如何,这是一个复杂的解决方案..
您想要的行为已经是InputStreamReader
的默认行为。 所以没有必要自己指定它。 这足以:
final BufferedInputStream in = new BufferedInputStream(istream); final Reader inputReader = new InputStreamReader(in, StandardCharsets.UTF_8);