Записать строку в выходной поток


140

У меня есть несколько слушателей вывода, которые реализуют OutputStream. Это может быть либо запись PrintStream в стандартный вывод или файл, либо запись в память или любое другое место назначения вывода; поэтому я указал OutputStream как () аргумент в методе.

Теперь я получил строку. Как лучше всего писать здесь в потоки?

Должен ли я просто использовать Writer.write (message.getBytes ())? Я могу передать ему байты, но если целевой поток является символьным, будет ли он преобразован автоматически?

Нужно ли мне вместо этого использовать мостовые потоки?


2
Я не уверен, но это похоже на то, что вы пытаетесь здесь изобрести колесо, просматривали ли вы Java Base API, а также Commons IO API?
posdef 01

Ответы:


152

Потоки ( InputStreamи OutputStream) передают двоичные данные. Если вы хотите записать строку в поток, вы должны сначала преобразовать ее в байты или, другими словами, закодировать ее. Вы можете сделать это вручную (как вы предлагаете), используя String.getBytes(Charset)метод, но вам следует избегать этого String.getBytes()метода, поскольку он использует кодировку JVM по умолчанию, которую нельзя надежно предсказать переносимым способом.

Однако обычный способ записи символьных данных в поток - это заключить поток в объект Writer(часто a PrintWriter), который выполняет преобразование за вас, когда вы вызываете его write(String)(или print(String)) метод. Соответствующая оболочка для InputStreams - это Reader .

PrintStream- это особая OutputStreamреализация в том смысле, что она также содержит методы, которые автоматически кодируют строки (внутренне использует средство записи). Но это все же ручей. Вы можете безопасно обернуть свой поток писателем, независимо от того, является ли он PrintStreamреализацией потока или какой-либо другой. Нет опасности двойного кодирования.

Пример PrintWriter с OutputStream:

try (PrintWriter p = new PrintWriter(new FileOutputStream("output-text.txt", true))) {
    p.println("Hello");
} catch (FileNotFoundException e1) {
    e1.printStackTrace();
}

4
Так что использование PrintWriterпохоже на использование String.getBytes(). Он использует любую случайную кодировку, которая является значением JVM по умолчанию. Так что это работает, только если вам повезет.
Christoffer Hammarström

108

OutputStream записывает байты, String предоставляет символы. Вам необходимо определить Charset для кодирования строки в byte []:

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

Измените UTF-8кодировку по вашему выбору.


3
Добавьте следующую строку. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Сахил Патель

.getBytes(StandardCharsets.UTF_8)немного чище
Sadap

32

Вы можете создать оболочку PrintStream вокруг OutputStream, а затем просто вызвать ее print (String):

final OutputStream os = new FileOutputStream("/tmp/out");
final PrintStream printStream = new PrintStream(os);
printStream.print("String");
printStream.close();

2
Какой набор символов использует PrintStream для преобразования в байты?
Дин Хиллер


12

Оберните свой OutputStream в PrintWriter и используйте методы печати этого класса. Они принимают String и делают всю работу за вас.


9

Вы можете использовать Apache Commons IO :

try (OutputStream outputStream = ...) {
    IOUtils.write("data", outputStream, "UTF-8");
}

IOUtils.write(String data, OutputStream output, Charset encoding)реализован как output.write(data.getBytes(Charsets.toCharset(encoding))), поэтому может, если закодированная строка не помещается в массив байтов
Шарунас
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.