Какой лучший способ передать вывод из java.io.OutputStream в String в Java?
Скажем, у меня есть метод:
writeToStream(Object o, OutputStream out)
Которая записывает определенные данные из объекта в данный поток. Однако я хочу, чтобы этот вывод был как можно проще в виде строки.
Я подумываю написать такой класс (непроверенный):
class StringOutputStream extends OutputStream {
StringBuilder mBuf;
public void write(int byte) throws IOException {
mBuf.append((char) byte);
}
public String getString() {
return mBuf.toString();
}
}
Но есть ли способ лучше? Я только хочу провести тест!
В данном случае да. Однако хороший момент - я об этом не подумал.




Я бы использовал ByteArrayOutputStream. А по окончании можно вызвать:
new String( baos.toByteArray(), codepage );
или лучше:
baos.toString( codepage );
Для конструктора Stringcodepage может быть String или экземпляром java.nio.charset.Charset. Возможное значение - java.nio.charset.StandardCharsets.UTF_8.
Метод toString() принимает только String в качестве параметра codepage (стенд Java 8).
ByteArrayOutputStream не имеет метода toArray (); хотя у него есть toByteArray (). Вы можете исправить ответ? Кроме того, почему бы не использовать baos.toString (String charsetName), что было бы немного проще.
Спасибо за подсказку с toString (кодировка). Я никогда не смотрел на toString, потому что ожидал ByteArrayOutputStream @ 123456. Я также исправил ошибку с помощью toByteArray ().
Также обратите внимание, что некоторые кодовые страницы не устанавливаются, если вы явно не запрашиваете их при пользовательской установке.
может просто вернуть baos.toString (), для чего нужна функция coepage?
Bytearray - это просто двоичные данные. Поскольку (unicode) текст может быть закодирован в двоичном формате множеством различных способов, ByteArrayOutputStream должен знать, какая кодировка использовалась для кодирования байтов, чтобы он мог использовать ту же кодировку для повторного декодирования байтов в строку. Простое использование toString без аргумента неразумно, поскольку вы просто игнорируете проблему, вместо того чтобы решать ее; Java будет использовать кодировку платформы, которая может быть правильной ... или нет. В основном это случайность. Вам нужно выяснить, какая кодировка использовалась для записи текста в байты, и передать эту кодировку toString.
Просто пояснение по кодовой странице, на которую здесь есть ссылка: в Java вы можете использовать Charset.defaultCharset () или Charset.forName («конкретная кодировка»); Для меня сработало: new String (baos.toByteArray (), Charset.defaultCharset ());
@WallaceBrown с использованием defaultCharset не лучше, чем полное игнорирование кодировки - вам нужно выяснить, что это такое, прежде чем использовать toString
@artbristol: Хотя ваши предупреждения о defaultCharset технически верны, кажется, что для этого случая (модульного теста) это не имеет значения - строка будет кодироваться и декодироваться на той же машине во время одного и того же выполнения программы. Здесь действительно нет риска, что будут использоваться разные кодовые страницы.
@TomasLycken Да, вы правы, если он и кодируется, и декодируется на одной машине, это нормально. Хотя что, если модульный тест сравнивает результат с некоторой фиксированной строкой?
@TomasLycken, только если писатель также использует defaultCharset.
StandardCharsets.UTF_8 - это Charset, а не String. Причем параметр называется charsetName, а не codepage.Мне нравится библиотека ввода-вывода Apache Commons. Взгляните на его версию ByteArrayOutputStream, которая имеет метод toString(String enc), а также toByteArray(). Использование существующих и надежных компонентов, таких как проект Commons, позволяет уменьшить размер кода и упростить его расширение и перепрофилирование.
Сэкономьте себе год своей жизни и ознакомьтесь со всеми распространенными API-интерфейсами, чтобы, столкнувшись с проблемой, вы могли использовать полностью протестированное и принадлежащее сообществу решение.
Хм, я заядлый пользователь Apache Commons, но в данном случае я не понимаю, почему вы должны использовать ByteArrayOutputStream Commons IO вместо собственного java.io.ByteArrayOutputStream JDK. Последний также предоставляет методы toString (String charsetName) и toByteArray (). Хотите уточнить?
Да, поскольку исходный контекст был лучшим способом потоковой передачи и извлечения контента, я включил пример Commons IO, поскольку он включал метод write (InputStream) для тогда еще неопределенного / сомнительного механизма для заполнения OutputStream. Я бы тоже пошел с JDK.
Вот что я в итоге сделал:
Obj.writeToStream(toWrite, os);
try {
String out = new String(os.toByteArray(), "UTF-8");
assertTrue(out.contains("testString"));
} catch (UnsupportedEncondingException e) {
fail("Caught exception: " + e.getMessage());
}
Где os - это ByteArrayOutputStream.
@JavaJigs Я разъяснил это внизу своего ответа почти 5 лет назад :)
Рассмотрите возможность замены "UTF-8" на StandardCharsets.UTF_8.
Это прекрасно сработало
OutputStream output = new OutputStream() {
private StringBuilder string = new StringBuilder();
@Override
public void write(int b) throws IOException {
this.string.append((char) b );
}
//Netbeans IDE automatically overrides this toString()
public String toString() {
return this.string.toString();
}
};
вызов метода = >> marshaller.marshal( (Object) toWrite , (OutputStream) output);
затем, чтобы распечатать строку или получить ее, просто укажите сам "выходной" поток
Например, чтобы вывести строку на консоль = >> System.out.println(output);
К вашему сведению: мой вызов метода marshaller.marshal(Object,Outputstream) предназначен для работы с XML. Это не имеет отношения к этой теме.
Это очень расточительно для производственного использования, слишком много конверсий, и это немного плохо. Это просто было написано, чтобы доказать вам, что вполне возможно создать собственный OuputStream и вывести строку. Но просто идите по пути Horcrux7, и все будет хорошо с двумя вызовами методов.
И мир живет другим днем ....
Просто приведение байта к char будет работать только с ascii. Используйте ByteArrayOutputStream как Horcrux7
Согласен с Дэйвом Рэем. Вы не можете предположить, что ваш байт является символом ASCII. Вам нужно интерпретировать байты, используя кодировку. Используйте byteArrayOutputStream.toString («UTF-8») или новую строку (byteArrayOutputStream.toByteArray (), «UTF-8»).
baos.toString(StandardCharsets.UTF_8);
Converts the buffer's contents into a string by decoding the bytes using the named charset.
Почти копипаст из фрагмента принятого ответа, позор вам
Я считаю, что мой ответ более точен. Фактически это копия документа оракула (ссылка, которую я опубликовал).
У вас только байты ASCII? Вам не нужна кодовая страница?