Dengan mengacu pada utas berikut: Aplikasi Java: Tidak dapat membaca file yang disandikan iso-8859-1 dengan benar
Apa cara terbaik untuk menentukan secara sistematis pengkodean charset dari inputstream / file?
Saya sudah mencoba menggunakan yang berikut ini:
File in = new File(args[0]);
InputStreamReader r = new InputStreamReader(new FileInputStream(in));
System.out.println(r.getEncoding());
Tetapi pada file yang saya tahu akan dikodekan dengan ISO8859_1 kode di atas menghasilkan ASCII, yang tidak benar, dan tidak memungkinkan saya untuk dengan benar membuat konten file kembali ke konsol.
Reader.getEncoding
mengembalikan penyandian yang diatur pembaca untuk digunakan, yang dalam kasus Anda adalah penyandian default.Jawaban:
Saya telah menggunakan perpustakaan ini, mirip dengan jchardet untuk mendeteksi pengodean di Java: http://code.google.com/p/juniversalchardet/
sumber
Anda tidak dapat menentukan pengodean byte stream yang sewenang-wenang. Ini adalah sifat dari pengkodean. Pengkodean berarti pemetaan antara nilai byte dan perwakilannya. Jadi, setiap penyandian "bisa" benar.
Metode getEncoding () akan mengembalikan pengkodean yang telah diatur (baca JavaDoc ) untuk stream. Tidak akan menebak pengodean untuk Anda.
Beberapa aliran memberi tahu Anda penyandian mana yang digunakan untuk membuatnya: XML, HTML. Tapi bukan aliran byte yang sewenang-wenang.
Bagaimanapun, Anda bisa mencoba menebak penyandian sendiri jika perlu. Setiap bahasa memiliki frekuensi yang sama untuk setiap karakter. Dalam bahasa Inggris char e muncul sangat sering tetapi ê akan muncul sangat sangat jarang. Dalam aliran ISO-8859-1 biasanya tidak ada karakter 0x00. Tetapi stream UTF-16 memiliki banyak dari mereka.
Atau: Anda bisa bertanya kepada pengguna. Saya telah melihat aplikasi yang memberikan Anda potongan file dalam penyandian yang berbeda dan meminta Anda untuk memilih yang "benar".
sumber
lihat ini: http://site.icu-project.org/ (icu4j) mereka memiliki perpustakaan untuk mendeteksi charset dari IOStream bisa sederhana seperti ini:
sumber
Inilah favorit saya:
TikaEncodingDetector
Ketergantungan:
Sampel:
GuessEncoding
Ketergantungan:
Sampel:
sumber
CharsetDectector
.Anda tentu dapat memvalidasi file untuk charset tertentu dengan mendekodekannya dengan
CharsetDecoder
dan mengawasi kesalahan "input salah bentuk" atau "karakter tidak dapat dipetakan". Tentu saja, ini hanya memberi tahu Anda jika charset salah; itu tidak memberi tahu Anda apakah itu benar. Untuk itu, Anda memerlukan dasar perbandingan untuk mengevaluasi hasil yang diterjemahkan, mis. Anda tahu sebelumnya jika karakter dibatasi untuk beberapa bagian, atau apakah teks mematuhi beberapa format yang ketat? Intinya adalah bahwa deteksi charset adalah dugaan tanpa jaminan.sumber
Perpustakaan mana yang digunakan?
Pada tulisan ini, mereka adalah tiga perpustakaan yang muncul:
Saya tidak memasukkan Apache Any23 karena menggunakan ICU4j 3.4 di bawah tenda.
Bagaimana cara mengetahui charset yang tepat (atau sedekat mungkin) yang terdeteksi ?
Tidak mungkin mengesahkan charset yang terdeteksi oleh masing-masing pustaka di atas. Namun, dimungkinkan untuk meminta mereka secara bergantian dan menilai respons yang dikembalikan.
Bagaimana cara mencetak respons yang dikembalikan?
Setiap respons dapat diberikan satu poin. Semakin banyak poin yang dimiliki respons, semakin percaya diri charset yang terdeteksi. Ini adalah metode penilaian sederhana. Anda bisa menguraikan orang lain.
Apakah ada kode sampel?
Berikut ini cuplikan lengkap yang mengimplementasikan strategi yang dijelaskan dalam baris sebelumnya.
Perbaikan: The
guessEncoding
Metode membaca inputstream sepenuhnya. Untuk aliran input yang besar ini dapat menjadi perhatian. Semua perpustakaan ini akan membaca seluruh inputstream. Ini akan menyiratkan konsumsi waktu yang besar untuk mendeteksi rangkaian karakter.Dimungkinkan untuk membatasi pemuatan data awal hingga beberapa byte dan melakukan deteksi charset hanya pada beberapa byte tersebut.
sumber
Lib di atas adalah detektor BOM sederhana yang tentu saja hanya berfungsi jika ada BOM di awal file. Lihatlah http://jchardet.sourceforge.net/ yang memindai teks
sumber
Sejauh yang saya tahu, tidak ada perpustakaan umum dalam konteks ini yang cocok untuk semua jenis masalah. Jadi, untuk setiap masalah Anda harus menguji perpustakaan yang ada dan memilih yang terbaik yang memenuhi kendala masalah Anda, tetapi seringkali tidak ada satupun yang sesuai. Dalam kasus ini Anda dapat menulis Encoding Detector Anda sendiri! Seperti yang saya tulis ...
Saya telah menulis alat java meta untuk mendeteksi pengkodean charset dari halaman Web HTML, menggunakan IBM ICU4j dan Mozilla JCharDet sebagai komponen bawaan. Di sini Anda dapat menemukan alat saya, silakan baca bagian README sebelum yang lain. Selain itu, Anda dapat menemukan beberapa konsep dasar masalah ini di makalah saya dan dalam rujukannya.
Di bawah ini saya memberikan beberapa komentar bermanfaat yang saya alami dalam pekerjaan saya:
sumber
Saya menemukan perpustakaan pihak ketiga yang bagus yang dapat mendeteksi pengkodean aktual: http://glaforge.free.fr/wiki/index.php?wiki=GuessEncoding
Saya tidak mengujinya secara luas tetapi tampaknya berhasil.
sumber
Jika Anda menggunakan ICU4J ( http://icu-project.org/apiref/icu4j/ )
Ini kode saya:
Ingatlah untuk meletakkan semua try-catch membutuhkannya.
Saya harap ini berhasil untuk Anda.
sumber
Jika Anda tidak tahu penyandian data Anda, itu tidak mudah untuk ditentukan, tetapi Anda bisa mencoba menggunakan perpustakaan untuk menebaknya . Juga, ada pertanyaan serupa .
sumber
Untuk file ISO8859_1, tidak ada cara mudah untuk membedakannya dari ASCII. Namun demikian, untuk file Unicode orang dapat mendeteksi ini berdasarkan beberapa byte pertama dari file tersebut.
File UTF-8 dan UTF-16 termasuk Byte Order Mark (BOM) di bagian paling awal file. BOM adalah ruang tanpa putus lebar nol.
Sayangnya, karena alasan historis, Java tidak mendeteksi ini secara otomatis. Program seperti Notepad akan memeriksa BOM dan menggunakan penyandian yang sesuai. Menggunakan unix atau Cygwin, Anda dapat memeriksa BOM dengan perintah file. Sebagai contoh:
Untuk Java, saya sarankan Anda memeriksa kode ini, yang akan mendeteksi format file umum dan memilih pengkodean yang benar: Cara membaca file dan secara otomatis menentukan pengkodean yang benar
sumber
Alternatif untuk TikaEncodingDetector adalah dengan menggunakan Tika AutoDetectReader .
sumber
Di Jawa polos:
Pendekatan ini akan mencoba pengkodean satu per satu sampai satu berhasil atau kita kehabisan. (BTW daftar penyandian saya hanya memiliki item-item itu karena itu adalah implementasi rangkaian karakter yang diperlukan pada setiap platform Java, https://docs.oracle.com/javase/9/docs/api/java/nio/charset/Charset.html )
sumber
Bisakah Anda memilih set char yang sesuai di Konstruktor :
sumber