Saya membuat program wordcount sederhana di Java yang membaca file berbasis teks di direktori.
Namun, saya terus mendapatkan kesalahan:
java.nio.charset.MalformedInputException: Input length = 1
dari baris kode ini:
BufferedReader reader = Files.newBufferedReader(file,Charset.forName("UTF-8"));
Saya tahu saya mungkin mendapatkan ini karena saya menggunakan Charset
yang tidak menyertakan beberapa karakter dalam file teks, beberapa di antaranya menyertakan karakter bahasa lain. Tapi saya ingin memasukkan karakter itu.
Saya kemudian belajar di JavaDocs bahwa Charset
itu opsional dan hanya digunakan untuk pembacaan file yang lebih efisien, jadi saya mengubah kodenya menjadi:
BufferedReader reader = Files.newBufferedReader(file);
Tetapi beberapa file masih membuang file MalformedInputException
. Saya tidak tahu kenapa.
Saya bertanya-tanya apakah ada all-inclusive Charset
yang memungkinkan saya membaca file teks dengan berbagai jenis karakter ?
Terima kasih.
sumber
ISO-8859-1
dan itu bekerja dengan baik. Saya pikir itu untuk karakter Eropa, itu bagus. Saya masih tidak tahu mengapaUTF-16
tidak berhasil.ISO-8859-1
, maka tidakUTF-16
. Pengodean ini sangat berbeda. File tidak bisa menjadi keduanya.Membuat BufferedReader dari Files.newBufferedReader
Files.newBufferedReader(Paths.get("a.txt"), StandardCharsets.UTF_8);
saat menjalankan aplikasi itu mungkin memunculkan pengecualian berikut:
java.nio.charset.MalformedInputException: Input length = 1
Tapi
new BufferedReader(new InputStreamReader(new FileInputStream("a.txt"),"utf-8"));
bekerja dengan baik.
Perbedaannya adalah, yang pertama menggunakan tindakan default CharsetDecoder.
sedangkan yang terakhir menggunakan aksi REPLACE.
sumber
ISO-8859-1 adalah rangkaian karakter lengkap, dalam arti dijamin tidak akan memunculkan MalformedInputException. Jadi bagus untuk debugging, bahkan jika input Anda tidak ada di charset ini. Begitu:-
req.setCharacterEncoding("ISO-8859-1");
Saya memiliki beberapa karakter double-right-quote / double-left-quote dalam masukan saya, dan US-ASCII dan UTF-8 melemparkan MalformedInputException pada mereka, tetapi ISO-8859-1 berfungsi.
sumber
Saya juga mengalami pengecualian ini dengan pesan kesalahan,
java.nio.charset.MalformedInputException: Input length = 1 at java.nio.charset.CoderResult.throwException(Unknown Source) at sun.nio.cs.StreamEncoder.implWrite(Unknown Source) at sun.nio.cs.StreamEncoder.write(Unknown Source) at java.io.OutputStreamWriter.write(Unknown Source) at java.io.BufferedWriter.flushBuffer(Unknown Source) at java.io.BufferedWriter.write(Unknown Source) at java.io.Writer.write(Unknown Source)
dan menemukan bahwa beberapa bug aneh terjadi saat mencoba menggunakan
untuk menulis string "orazg 54" dari tipe generik di kelas.
//key is of generic type <Key extends Comparable<Key>> writer.write(item.getKey() + "\t" + item.getValue() + "\n");
String ini memiliki panjang 9 yang berisi karakter dengan poin kode berikut:
111 114 97 122103 9 53 52 10
Namun, jika BufferedWriter di kelas diganti dengan:
FileOutputStream outputStream = new FileOutputStream(filePath); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));
itu bisa berhasil menulis String ini tanpa pengecualian. Selain itu, jika saya menulis String yang sama yang dibuat dari karakter itu masih berfungsi dengan baik.
String string = new String(new char[] {111, 114, 97, 122, 103, 9, 53, 52, 10}); BufferedWriter writer = Files.newBufferedWriter(Paths.get("a.txt")); writer.write(string); writer.close();
Sebelumnya saya tidak pernah menemukan Exception saat menggunakan BufferedWriter pertama untuk menulis Strings. Ini adalah bug aneh yang terjadi pada BufferedWriter yang dibuat dari java.nio.file.Files.newBufferedWriter (jalur, opsi)
sumber
ISO_8859_1 Bekerja untuk saya! Saya sedang membaca file teks dengan nilai yang dipisahkan koma
sumber
coba ini .. saya memiliki masalah yang sama, implementasi di bawah ini berhasil untuk saya
lalu gunakan Pustaka di mana pun Anda inginkan.
depan:
CsvToBean<anyPojo> csvToBean = null; try { Reader reader = Files.newBufferedReader(Paths.get(csvFilePath), StandardCharsets.ISO_8859_1); csvToBean = new CsvToBeanBuilder(reader) .withType(anyPojo.class) .withIgnoreLeadingWhiteSpace(true) .withSkipLines(1) .build(); } catch (IOException e) { e.printStackTrace(); }
sumber
Saya menulis berikut ini untuk mencetak daftar hasil ke standar berdasarkan charsets yang tersedia. Perhatikan bahwa ini juga memberi tahu Anda baris apa yang gagal dari nomor baris berbasis 0 jika Anda memecahkan masalah karakter apa yang menyebabkan masalah.
public static void testCharset(String fileName) { SortedMap<String, Charset> charsets = Charset.availableCharsets(); for (String k : charsets.keySet()) { int line = 0; boolean success = true; try (BufferedReader b = Files.newBufferedReader(Paths.get(fileName),charsets.get(k))) { while (b.ready()) { b.readLine(); line++; } } catch (IOException e) { success = false; System.out.println(k+" failed on line "+line); } if (success) System.out.println("************************* Successs "+k); } }
sumber
Nah, masalahnya adalah yang
Files.newBufferedReader(Path path)
diimplementasikan seperti ini:public static BufferedReader newBufferedReader(Path path) throws IOException { return newBufferedReader(path, StandardCharsets.UTF_8); }
jadi pada dasarnya tidak ada gunanya menentukan
UTF-8
kecuali Anda ingin deskriptif dalam kode Anda. Jika Anda ingin mencoba rangkaian karakter yang "lebih luas", Anda dapat mencobanyaStandardCharsets.UTF_16
, tetapi Anda tidak dapat 100% yakin untuk mendapatkan setiap karakter yang memungkinkan.sumber
Anda dapat mencoba sesuatu seperti ini, atau cukup salin dan tempel bagian di bawah ini.
boolean exception = true; Charset charset = Charset.defaultCharset(); //Try the default one first. int index = 0; while(exception) { try { lines = Files.readAllLines(f.toPath(),charset); for (String line: lines) { line= line.trim(); if(line.contains(keyword)) values.add(line); } //No exception, just returns exception = false; } catch (IOException e) { exception = true; //Try the next charset if(index<Charset.availableCharsets().values().size()) charset = (Charset) Charset.availableCharsets().values().toArray()[index]; index ++; } }
sumber
while(exception)
loop selamanya jika tidak pernah menemukan charset yang berfungsi dalam larik. Pengendali pengecualian harus memutar ulang jika akhir larik tercapai dan tidak ada rangkaian karakter yang berfungsi ditemukan. Juga, pada saat penulisan, jawaban ini memiliki suara "-2". Saya telah memilihnya menjadi "-1". Saya kira alasan mendapat suara negatif adalah karena penjelasan yang kurang memadai. Meskipun saya memahami fungsi kode tersebut, orang lain mungkin tidak. Jadi, komentar seperti "Anda bisa mencoba yang seperti ini" mungkin tidak disukai oleh sebagian orang.UTF-8 bekerja untuk saya dengan karakter Polandia
sumber