当我遇到类似的问题时,我使用Perl脚本来确保数据被转换为有效的UTF-8,使用类似以下代码:
use Encode;
binmode(STDOUT, ":utf8");
while (<>) {
print Encode::decode('UTF-8', $_);
}
该脚本接受可能损坏的UTF-8格式的输入,在stdin
中重新打印有效的UTF-8格式到stdout
。无效的字符将被替换为�
(U+FFFD
,Unicode替换字符)。
如果您在良好的UTF-8格式输入上运行此脚本,则输出应与输入完全相同。
如果您的数据存储在数据库中,则使用DBI扫描您的表并使用此方法清理所有数据是有意义的,以确保所有内容都是有效的UTF-8格式。
这是同样脚本的Perl一行版本:
perl -MEncode -e "binmode STDOUT,':utf8';while(<>){print Encode::decode 'UTF-8',\$_}" < bad.txt > good.txt
编辑:添加了仅适用于Java的解决方案.
以下是如何在Java中实现此示例:
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
public class UtfFix {
public static void main(String[] args) throws InterruptedException, CharacterCodingException {
CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
decoder.onMalformedInput(CodingErrorAction.REPLACE);
decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
ByteBuffer bb = ByteBuffer.wrap(new byte[] {
(byte) 0xD0, (byte) 0x9F,
(byte) 0xD1, (byte) 0x80,
(byte) 0xD0,
(byte) 0xD0, (byte) 0xB2,
(byte) 0xD0, (byte) 0xB5,
(byte) 0xD1, (byte) 0x82
});
CharBuffer parsed = decoder.decode(bb);
System.out.println(parsed);
}
}
$_
变量添加了一个反斜杠。 - Diego Sevilla