Ketika saya mengalami masalah seperti ini, saya menggunakan skrip Perl untuk memastikan bahwa data dikonversi ke UTF-8 yang valid dengan menggunakan kode seperti ini:
use Encode;
binmode(STDOUT, ":utf8");
while (<>) {
print Encode::decode('UTF-8', $_);
}
Skrip ini menggunakan (mungkin rusak) UTF-8 pada stdin
dan mencetak ulang UTF-8 yang valid ke stdout
. Karakter yang tidak valid diganti dengan �
(U+FFFD
, karakter pengganti Unicode
).
Jika Anda menjalankan skrip ini pada input UTF-8 yang baik, output harus sama dengan input.
Jika Anda memiliki data dalam database, masuk akal untuk menggunakan DBI untuk memindai tabel Anda dan menggosok semua data menggunakan pendekatan ini untuk memastikan bahwa semuanya adalah UTF-8 yang valid.
Ini adalah versi satu baris Perl dari skrip yang sama ini:
perl -MEncode -e "binmode STDOUT,':utf8';while(<>){print Encode::decode 'UTF-8',\$_}" < bad.txt > good.txt
EDIT:Menambahkan solusi khusus Java .
Ini adalah contoh bagaimana melakukan ini di 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, // 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: Пр?вет
}
}