Tulis string ke aliran output

139

Saya memiliki beberapa pendengar keluaran yang mengimplementasikan OutputStream. Ini bisa berupa PrintStream yang menulis ke stdout atau ke File, atau dapat menulis ke memori atau tujuan output lainnya; oleh karena itu, saya menetapkan OutputStream sebagai (an) argumen dalam metode ini.

Sekarang, saya telah menerima String. Apa cara terbaik untuk menulis ke streaming di sini?

Haruskah saya menggunakan Writer.write (message.getBytes ())? Saya bisa memberikannya byte, tetapi jika aliran tujuan adalah aliran karakter maka apakah akan dikonversi secara otomatis?

Apakah saya perlu menggunakan beberapa stream jembatan di sini?

yart
sumber
2
Saya tidak yakin tetapi ini terdengar seperti Anda mencoba untuk menemukan kembali roda di sini, apakah Anda telah melihat melalui Java Base API, serta Commons IO API?
posdef

Jawaban:

149

Streaming ( InputStreamdan OutputStream) mentransfer data biner . Jika Anda ingin menulis string ke stream, Anda harus terlebih dahulu mengubahnya menjadi byte, atau dengan kata lain menyandikannya . Anda dapat melakukannya secara manual (seperti yang Anda sarankan) menggunakan String.getBytes(Charset)metode ini, tetapi Anda harus menghindari String.getBytes()metode tersebut, karena itu menggunakan pengodean default JVM, yang tidak dapat diprediksi dengan andal dengan cara portabel.

Namun, cara biasa untuk menulis data karakter ke stream adalah dengan membungkus stream dalam a Writer, (seringkali a PrintWriter), yang melakukan konversi untuk Anda ketika Anda memanggil metode write(String)(atau print(String)). Pembungkus yang sesuai untuk InputStreams adalah Pembaca .

PrintStreamadalah OutputStreamimplementasi khusus dalam arti bahwa itu juga berisi metode yang secara otomatis menyandikan string (menggunakan penulis internal). Tapi itu masih aliran. Anda dapat dengan aman membungkus aliran Anda dengan seorang penulis, tidak peduli apakah itu adalah PrintStreamimplementasi aliran atau lainnya. Tidak ada bahaya pengkodean ganda.

Contoh PrintWriter dengan OutputStream:

try (PrintWriter p = new PrintWriter(new FileOutputStream("output-text.txt", true))) {
    p.println("Hello");
} catch (FileNotFoundException e1) {
    e1.printStackTrace();
}
MForster
sumber
3
Jadi menggunakan PrintWritersama seperti menggunakan String.getBytes(). Ia menggunakan pengodean acak apa pun yang merupakan default JVM. Jadi itu hanya berfungsi jika Anda beruntung.
Christoffer Hammarström
106

OutputStream menulis byte, String menyediakan karakter. Anda perlu mendefinisikan Charset untuk menyandikan string ke byte []:

outputStream.write(string.getBytes(Charset.forName("UTF-8")));

Ubah UTF-8ke rangkaian pilihan Anda.

Peter Knego
sumber
3
Tambahkan dengan baris berikut. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Sahil Patel
32

Anda dapat membuat PrintStream membungkus OutputStream Anda dan kemudian panggil saja print itu (String):

final OutputStream os = new FileOutputStream("/tmp/out");
final PrintStream printStream = new PrintStream(os);
printStream.print("String");
printStream.close();
Illarion Kovalchuk
sumber
2
Apa set karakter yang digunakan PrintStream untuk mengkonversi ke byte?
Dean Hiller
20

Dengan desain itu harus dilakukan dengan cara ini:

OutputStream out = ...;
try (Writer w = new OutputStreamWriter(out, "UTF-8")) {
    w.write("Hello, World!");
} // or w.close(); //close will auto-flush
Antonio
sumber
3
Perhatikan bahwa w.close()akan menutup outjuga.
Franklin Yu
12

Bungkus OutputStream Anda dengan PrintWriter dan gunakan metode cetak pada kelas itu. Mereka menerima sebuah String dan melakukan pekerjaan untuk Anda.

NG.
sumber
9

Anda dapat menggunakan Apache Commons IO :

try (OutputStream outputStream = ...) {
    IOUtils.write("data", outputStream, "UTF-8");
}
Felix
sumber
IOUtils.write(String data, OutputStream output, Charset encoding)diimplementasikan sebagai output.write(data.getBytes(Charsets.toCharset(encoding))), jadi mungkin jika string yang dikodekan tidak dapat ditampung dalam array byte
Šarūnas