Napisz ciąg do strumienia wyjściowego

139

Mam kilka odbiorników wyjściowych, które implementują OutputStream. Może to być PrintStream zapisujący na standardowe wyjście lub do pliku, albo może to być zapis do pamięci lub innego miejsca docelowego wyjściowego; w związku z tym określiłem OutputStream jako argument () w metodzie.

Teraz otrzymałem String. Jaki jest tutaj najlepszy sposób pisania do strumieni?

Czy powinienem po prostu użyć Writer.write (message.getBytes ())? Mogę podać bajty, ale jeśli strumień docelowy jest strumieniem znaków, to czy będzie konwertowany automatycznie?

Czy zamiast tego muszę używać tutaj niektórych strumieni mostowych?

yart
źródło
2
Nie jestem pewien, ale brzmi to tak, jakbyś próbował odkryć koło na nowo, czy przejrzałeś Java Base API, a także Commons IO API?
posdef

Odpowiedzi:

149

Strumienie ( InputStreami OutputStream) przesyłają dane binarne . Jeśli chcesz zapisać ciąg w strumieniu, musisz najpierw przekonwertować go na bajty, czyli innymi słowy zakodować . Możesz to zrobić ręcznie (jak sugerujesz) za pomocą tej String.getBytes(Charset)metody, ale powinieneś jej unikać String.getBytes(), ponieważ używa ona domyślnego kodowania JVM, którego nie można wiarygodnie przewidzieć w przenośny sposób.

Zwykłym sposobem zapisywania danych znakowych w strumieniu jest jednak umieszczenie strumienia w a Writer(często a PrintWriter), który dokonuje konwersji za Ciebie, gdy wywołujesz jego metodę write(String)(lub print(String)). Odpowiednim opakowaniem dla InputStreams jest czytnik .

PrintStreamjest specjalną OutputStreamimplementacją w tym sensie, że zawiera również metody, które automatycznie kodują ciągi znaków (wykorzystuje wewnętrznie program zapisujący). Ale to wciąż jest strumień. Możesz bezpiecznie opakować swój strumień w program zapisujący, bez względu na to, czy jest to PrintStreamimplementacja strumienia, czy inna. Nie ma niebezpieczeństwa podwójnego kodowania.

Przykład PrintWriter z OutputStream:

try (PrintWriter p = new PrintWriter(new FileOutputStream("output-text.txt", true))) {
    p.println("Hello");
} catch (FileNotFoundException e1) {
    e1.printStackTrace();
}
MForster
źródło
3
Więc używanie PrintWriterjest jak używanie String.getBytes(). Używa dowolnego losowego kodowania, które jest domyślne dla maszyny JVM. Więc działa tylko wtedy, gdy masz szczęście.
Christoffer Hammarström
106

OutputStream zapisuje bajty, String zapewnia znaki. Musisz zdefiniować zestaw znaków, aby zakodować ciąg do bajtu []:

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

Zmień UTF-8na wybrany przez siebie zestaw znaków.

Peter Knego
źródło
3
Dołącz następującą linią. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Sahil Patel
32

Możesz utworzyć PrintStream zawijający się wokół swojego OutputStream, a następnie po prostu wywołać jego print (String):

final OutputStream os = new FileOutputStream("/tmp/out");
final PrintStream printStream = new PrintStream(os);
printStream.print("String");
printStream.close();
Illarion Kovalchuk
źródło
2
Jakiego zestawu znaków używa PrintStream do konwersji na bajty?
Dean Hiller
20

Z założenia należy to zrobić w następujący sposób:

OutputStream out = ...;
try (Writer w = new OutputStreamWriter(out, "UTF-8")) {
    w.write("Hello, World!");
} // or w.close(); //close will auto-flush
Antonio
źródło
3
Zauważ, że w.close()to również się zamknie out.
Franklin Yu
12

Owiń swoje OutputStream za pomocą PrintWriter i użyj metod drukowania tej klasy. Biorą strunę i wykonują pracę za Ciebie.

NG.
źródło
9

Możesz użyć Apache Commons IO :

try (OutputStream outputStream = ...) {
    IOUtils.write("data", outputStream, "UTF-8");
}
Felix
źródło
IOUtils.write(String data, OutputStream output, Charset encoding)jest zaimplementowany jako output.write(data.getBytes(Charsets.toCharset(encoding))), więc może być, jeśli zakodowany ciąg nie zmieści się w tablicy bajtów
Šarūnas