it-swarm-id.com

Bagaimana cara mengubah Reader ke InputStream dan Writer ke OutputStream?

Apakah ada cara mudah untuk menghindari berurusan dengan masalah pengkodean teks?

87
Andrei Savu

Anda tidak dapat benar-benar menghindari berurusan dengan masalah penyandian teks, tetapi ada solusi yang ada:

Anda hanya perlu memilih penyandian pilihan Anda.

43
Peter

Jika Anda memulai dengan sebuah String, Anda juga dapat melakukan hal berikut:

new ByteArrayInputStream(inputString.getBytes("UTF-8"))
93
Ritesh Tendulkar

Nah, Pembaca berurusan dengan karakter dan InputStream menangani byte. Pengkodean menentukan bagaimana Anda ingin mewakili karakter Anda sebagai byte, sehingga Anda tidak bisa mengabaikan masalah tersebut. Sedangkan untuk menghindari masalah, pendapat saya adalah: pilih satu charset (mis. "UTF-8") dan tetap menggunakannya.

Mengenai cara melakukannya, seperti yang telah ditunjukkan, " nama yang jelas untuk kelas ini adalah ReaderInputStream dan WriterOutputStream . "Anehnya," ini tidak termasuk dalam Java perpustakaan "meskipun kelas 'lawan', InputStreamReader dan OutputStreamWriter sudah termasuk .

Jadi, banyak orang datang dengan implementasi mereka sendiri, termasuk Apache Commons IO . Bergantung pada masalah perizinan, Anda mungkin dapat memasukkan perpustakaan commons-io dalam proyek Anda, atau bahkan menyalin sebagian dari kode sumber (yang dapat diunduh di sini ).

Seperti yang Anda lihat, dokumentasi kedua kelas menyatakan bahwa "semua pengkodean charset yang didukung oleh JRE ditangani dengan benar".

N.B. Sebuah komentar pada salah satu jawaban lain di sini menyebutkan bug ini . Tapi itu mempengaruhi Apache Semut kelas ReaderInputStream ( di sini ), tidak Apache Commons IO kelas ReaderInputStream.

41
Peter Ford

Juga perhatikan bahwa, jika Anda memulai dengan sebuah String, Anda dapat melewatkan membuat StringReader dan membuat InputStream dalam satu langkah menggunakan org.Apache.commons.io.IOUtils from Commons IO seperti itu:

InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");

Tentu saja Anda masih perlu memikirkan tentang pengkodean teks, tetapi setidaknya konversi terjadi dalam satu langkah.

19
Phil Harvey

Menggunakan:

new CharSequenceInputStream(html, StandardCharsets.UTF_8);

Dengan cara ini tidak memerlukan konversi dimuka ke String dan kemudian ke byte[], yang mengalokasikan lebih banyak memori tumpukan, jika laporannya besar. Itu mengkonversi ke byte dengan cepat saat aliran dibaca, langsung dari StringBuffer.

Ini menggunakan CharSequenceInputStream dari Apache Commons IO proyek.

8
Oliv
7
Bozho

Anda tidak dapat menghindari masalah penyandian teks, tetapi Apache commons-io miliki

Perhatikan ini adalah perpustakaan yang dimaksud dalam jawaban Peter dari koders.com, cukup tautan ke perpustakaan alih-alih kode sumber.

5
dfrankow

Nama yang jelas untuk kelas ini adalah ReaderInputStream dan WriterOutputStream. Sayangnya ini tidak termasuk dalam pustaka Java. Namun, google adalah teman Anda.

Saya tidak yakin itu akan mengatasi semua masalah penyandian teks, yang merupakan mimpi buruk.

Ada RFE, tapi Ditutup, tidak akan diperbaiki.

5

Apakah Anda mencoba menulis konten Reader ke OutputStream? Jika demikian, Anda akan lebih mudah membungkus OutputStream dalam OutputStreamWriter dan menulis chars dari Reader ke Writer, alih-alih mencoba mengubah pembaca menjadi InputStream:

final Writer writer = new BufferedWriter(new OutputStreamWriter( urlConnection.getOutputStream(), "UTF-8" ) );
int charsRead;
char[] cbuf = new char[1024];
while ((charsRead = data.read(cbuf)) != -1) {
    writer.write(cbuf, 0, charsRead);
}
writer.flush();
// don't forget to close the writer in a finally {} block
4
Sam Barnum

Anda dapat menggunakan Cactoos (tidak ada metode statis, hanya objek):

Anda dapat mengonversi sebaliknya juga:

1
yegor256

Peringatan saat menggunakan WriterOutputStream - tidak selalu menangani penulisan data biner ke file dengan benar/sama dengan aliran output biasa. Saya memiliki masalah dengan ini yang membuat saya butuh waktu untuk melacak.

Jika Anda bisa, saya akan merekomendasikan menggunakan aliran output sebagai basis Anda, dan jika Anda perlu menulis string, gunakan pembungkus OUtputStreamWriter di sekitar aliran untuk melakukannya. Jauh lebih dapat diandalkan untuk mengonversi teks menjadi byte daripada sebaliknya, yang mungkin mengapa WriterOutputStream bukan bagian dari perpustakaan standar Java perpustakaan

1
romeara