PrintStream vs PrintWriter

Я искал сайт и нашел несколько ответов, но мне трудно понять разницу между этими двумя классами. Может ли кто-то объяснить различия между этими двумя классами?

Ответы

Ответ 1

PrintStream был оригинальным мостом для обработки символов кодирования и других типов данных. Если вы посмотрите на javadoc для java.io.OutputStream, вы увидите методы только для записи двух разных типов данных: byte и int.

В ранних версиях JDK (1.0.x), когда вы хотели писать символы, вы могли бы сделать одну из двух вещей, записать байты в выходной поток (которые предположительно входят в набор символов по умолчанию):

outputStream.write("foobar".getBytes());

или оберните другой выходной поток в PrintStream

PrintStream printStream = new PrintStream(outputStream);
printStream.write("foobar");

Посмотрите разницу? PrintStream обрабатывает преобразование символов в байтах, а также кодирование (вызов конструктора выше использует кодировку по умолчанию системы, но вы можете передать ее как параметр). Он также предоставляет удобные методы для написания двойных, булевых и т.д.

Фактически System.out и System.err определяются как экземпляры PrintStream.

В дополнение к JDK 1.1, и они понимают, что им нужен лучший способ справиться с чистыми символьными данными, поскольку у PrintStream все еще есть методы байт для записи. Таким образом, они представили абстрактный класс "Writer" для строгого описания символов, строковых и int-данных.

PrintWriter добавляет методы для других типов, таких как double, boolean и т.д.

В настоящее время PrintWriter также имеет методы format()/printf() для печати в формате и т.д.

Как правило, если вы пишете персональные данные, используйте экземпляры Writer. Если вы пишете двоичные (или смешанные) данные, используйте экземпляры OutputStream.

Ответ 2

Из Javadoc для PrintWriter:

Печать форматированных представлений объектов в поток текстового вывода. Этот класс реализует все методы печати, найденные в PrintStream. Он не содержит методов для записи необработанных байтов, для которых программа должна использовать незаписанные байтовые потоки.

Подумайте об этом так: a PrintStream сидит поверх некоторого OutputStream. Поскольку потоки вывода имеют дело с байтами, а не с символами, PrintStream должен нести ответственность за кодирование символов в байтах. OutputStream "просто" записывает байты в файл/консоль/сокет.

A PrintWriter, с другой стороны, находится поверх Writer. Поскольку Writer отвечает за кодирование символов в байтах, PrintWriter не выполняет кодирование. Я просто знаю о новостях и т.д. (Да, у PrintWriters есть конструкторы, которые принимают File и OutputStream s, но это просто удобства. Например, PrintWriter(OutputStream).

Создает новый PrintWriter без автоматической очистки линии от существующего OutputStream. Этот конструктор удобства создает необходимый промежуточный OutputStreamWriter, который преобразует символы в байты с использованием кодировки по умолчанию.

BTW. Если вы думаете, что PrintWriter действительно не имеет большой полезности, помните, что и PrintWriter, и PrintStream впитывают IOException из логики печати. ​​

Ответ 3

PrintStream используется для двоичного вывода (делает дополнительное преобразование), где PrintWriter предназначен для вывода текста (набора символов). PrintStream использует кодировку символов, зависящую от платформы, которая увеличивает проблемы с зависимостями платформы, что иногда вызывает проблемы при переходе с одной платформы на другую. С PrintWriter, как правило, мы можем указать, кодирование и, следовательно, может избежать зависимостей платформы. Internally PrintStream преобразует байты в символы в соответствии с правилами кодирования ОС. Но PrintWriter выполняет эту работу сразу (без преобразования char -byte). В строке ниже используется кодировка по умолчанию.

PrintStream stream = new PrintStream(output);

Теперь в случае PrintWriter

PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, "UTF-8"));

кодирование UTF-8; не зависит от платформы. Это преимущество с PrintWriter, где программист может управлять стилем кодирования. Из JDK 1.4 Java API позволяет также указать кодировку символов с помощью PrintStream. Таким образом, разница стала очень узкой, но для автоматической промывки. С PrintWriter также, когда включена автоматическая очистка, автоматическая промывка выполняется при каждом вызове методов печати. ​​

Ответ 4

Чтобы добавить ответ Matt:

Я сравнил PrintStream и PrintWriter, наиболее полезная часть, конструктор ClassName (String fileName, String charsetName), а функции print(), println(), printf()/format() поддерживаются обоими классами.

Различия заключаются в следующем:

Так как JDK1.0 vs JDK1.1

Конструкторы:

PrintStream(OutputStream out, boolean autoFlush, String charsetName)
PrintWriter(Writer wr)
PrintWriter(Writer wr, boolean autoFlush)

Методы, унаследованные от FilterOutputStream/OutputStream vs Writer, разница сводится к byte vs char:

PrintStream.write(byte[] buffer, int offset, int count)
PrintStream.write(byte[] buffer)
PrintStream.write(int oneByte)

PrintWriter.write(int oneChar)
PrintWriter.write(char[] buf)
PrintWriter.write(char[] buf, int offset, int count)
PrintWriter.write(String str)
PrintWriter.write(String str, int offset, int count)

PrintStream.printf() соответствует PrintWriter.format()

Это действительно выглядит в 1.1. они продумали лучший класс, но не смогли удалить старый класс 1.0 без нарушения существующих программ.