Membaca InputStream sebagai UTF-8

96

Saya mencoba membaca dari text/plainfile melalui internet, baris demi baris. Kode yang saya miliki sekarang adalah:

URL url = new URL("http://kuehldesign.net/test.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
LinkedList<String> lines = new LinkedList();
String readLine;

while ((readLine = in.readLine()) != null) {
    lines.add(readLine);
}

for (String line : lines) {
    out.println("> " + line);
}

File,, test.txtberisi ¡Hélló!, yang saya gunakan untuk menguji pengkodean.

Saat saya meninjau OutputStream( out), saya melihatnya sebagai > ¬°H√©ll√≥!. Saya tidak percaya ini adalah masalah OutputStreamkarena saya dapat melakukannya out.println("é");tanpa masalah.

Ada ide untuk membaca dari bentuk InputStreamUTF-8? Terima kasih!

Chris Kuehl
sumber
1
Protokol HTTP menentukan pengkodean. Mengapa Anda tidak menggunakan API perpustakaan yang menangani itu untuk Anda? Anda tidak perlu menebak pengkodean seperti ini. Saya tidak bermaksud negatif: Anda baik-baik saja! Saya hanya ingin tahu apakah tidak ada cara yang lebih mudah.
tchrist
1
text/plainSayangnya, saya tidak akan memiliki akses ke server yang menyajikan file dan tidak menggunakan pengkodean UTF-8. Saya tidak mengetahui adanya perpustakaan jaringan yang bagus; ada saran?
Chris Kuehl
1
Melihat dokumennya , saya tidak berpikir Anda harus menentukan pengkodean sama sekali. Saya terkejut mereka memberi Anda aliran byte! Anda memang memiliki akses ke URLConnection yang mendasari , dari mana Anda dapat memeriksa Pengkodean Konten, lalu membuka InputStreamReader dengan argumen yang benar. Pemeriksaan cepat terhadap sumber tidak menemukan apa pun yang tampaknya melakukan itu untuk Anda, yang tampaknya sangat timpang dan rawan kesalahan, jadi saya mungkin melewatkan sesuatu.
tchrist

Jawaban:

189

Memecahkan masalah saya sendiri. Garis ini:

BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));

perlu:

BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));

atau sejak Java 7:

BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8));
Chris Kuehl
sumber
3
Saya cukup yakin bahwa bentuk konstruktor tidak akan memunculkan pengecualian pada input yang tidak valid. Anda perlu menggunakan dengan CharsetDecoder decargumen. Ini adalah bug desain Java yang sama dengan yang dimiliki oleh OutputStreamWriterkonstruktor: hanya satu dari empat yang benar-benar merendahkan untuk memberi tahu Anda ketika terjadi kesalahan. Anda juga harus menggunakan CharsetDecoder decargumen mewah di sana. Satu-satunya hal yang aman dan waras untuk dilakukan adalah menganggap semua konstruktor lain tidak digunakan lagi, karena mereka tidak dapat dipercaya untuk berperilaku.
tchrist
6
Sejak Java 7 adalah mungkin untuk menulis menyediakan Charset sebagai Konstanta bukan sebagai StringStandardCharsets.UTF_8
tobijdc
18
String file = "";

try {

    InputStream is = new FileInputStream(filename);
    String UTF8 = "utf8";
    int BUFFER_SIZE = 8192;

    BufferedReader br = new BufferedReader(new InputStreamReader(is,
            UTF8), BUFFER_SIZE);
    String str;
    while ((str = br.readLine()) != null) {
        file += str;
    }
} catch (Exception e) {

}

Coba ini,.. :-)

Rohith
sumber
8
Alih-alih file + = str, buat StringBuilder dan tambahkan itu. Kompiler mungkin dapat mengoptimalkan penambahan string, tetapi kemungkinan menciptakan banyak sampah
seand
2
Jika Anda ingin mengubah BufferedReader menjadi string, gunakan Apache Commons, jangan temukan kembali wheal: String myStr = org.apache.commons.io.IOUtils.toString (myBufferedReaderInstance);
Jaime Marín
8
UTF8 = "utf8", variabel bagus;)
Nicofisi
7

Saya mengalami masalah yang sama setiap kali menemukan karakter khusus yang menandainya sebagai . untuk mengatasi ini, saya mencoba menggunakan pengkodean: ISO-8859-1

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("txtPath"),"ISO-8859-1"));

while ((line = br.readLine()) != null) {

}

Saya harap ini dapat membantu siapa saja yang melihat postingan ini.

joshua cleveland
sumber
1
Bisakah Anda menjelaskan karakter apa yang tidak didukung dalam UTF-8?
USM