Toen ik een dergelijk probleem had, gebruikte ik Perl-script om ervoor te zorgen dat gegevens worden geconverteerd naar geldige UTF-8 door code als volgt te gebruiken:
use Encode;
binmode(STDOUT, ":utf8");
while (<>) {
print Encode::decode('UTF-8', $_);
}
Dit script gebruikt (mogelijk beschadigde) UTF-8 op stdin
en drukt geldige UTF-8 opnieuw af naar stdout
. Ongeldige tekens worden vervangen door �
(U+FFFD
, Unicode-vervangend teken
).
Als u dit script uitvoert op goede UTF-8-invoer, moet de uitvoer identiek zijn aan de invoer.
Als u gegevens in de database heeft, is het logisch om DBI te gebruiken om uw tabel(len) te scannen en alle gegevens op deze manier te scrubben om er zeker van te zijn dat alles geldig is UTF-8.
Dit is de one-liner versie van Perl van hetzelfde script:
perl -MEncode -e "binmode STDOUT,':utf8';while(<>){print Encode::decode 'UTF-8',\$_}" < bad.txt > good.txt
EDIT:Java-only oplossing toegevoegd .
Dit is een voorbeeld van hoe u dit in Java doet:
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: Пр?вет
}
}