Als ich ein solches Problem hatte, habe ich Perl-Skript verwendet, um sicherzustellen, dass Daten in gültiges UTF-8 konvertiert werden, indem ich Code wie diesen verwende:
use Encode;
binmode(STDOUT, ":utf8");
while (<>) {
print Encode::decode('UTF-8', $_);
}
Dieses Skript verwendet (möglicherweise beschädigtes) UTF-8 auf stdin
und gibt gültiges UTF-8 nach stdout
aus . Ungültige Zeichen werden durch �
ersetzt (U+FFFD
, Unicode-Ersatzzeichen
).
Wenn Sie dieses Skript mit guter UTF-8-Eingabe ausführen, sollte die Ausgabe mit der Eingabe identisch sein.
Wenn Sie Daten in der Datenbank haben, ist es sinnvoll, DBI zu verwenden, um Ihre Tabelle(n) zu scannen und alle Daten mit diesem Ansatz zu bereinigen, um sicherzustellen, dass alles gültiges UTF-8 ist.
Dies ist die Perl-Einzeiler-Version desselben Skripts:
perl -MEncode -e "binmode STDOUT,':utf8';while(<>){print Encode::decode 'UTF-8',\$_}" < bad.txt > good.txt
BEARBEITEN:Nur-Java-Lösung hinzugefügt .
Dies ist ein Beispiel, wie man das in Java macht:
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, // corrupted UTF-8, was 'и'
(byte) 0xD0, (byte) 0xB2, // 'в'
(byte) 0xD0, (byte) 0xB5, // 'е'
(byte) 0xD1, (byte) 0x82 // 'т'
});
CharBuffer parsed = decoder.decode(bb);
System.out.println(parsed);
// this prints: Пр?вет
}
}