Когда использовать, какой писатель подкласс в Java; общие практики
Вопрос
Я всегда слегка путался с количеством различных реализаций IO в Java, и теперь, когда я полностью застрял в своем развитии проекта, я забираю время, чтобы прочитать полезные вещи.
Я понял, что нет возможности для новичков сравнения (кроме коротких объяснений в API для класса писателя) между различными подклассами Writer
сорт. Поэтому я подумал, что уволил вопрос, для чего хороши эти разные подклассы?
Например, я обычно использую FileWriter
обернутый с А. BufferedWriter
для моих выходов к файлам, но я всегда раздражен тем, что нет println()
как метод, и нужно использовать newLine()
каждая вторая строка (чтобы сделать вывод читаемого человека). PrintWriter
имеет println()
Метод, но нет конструктора, который поддерживает присоединение, однако ...
Я бы очень признателен, если бы вы могли дать мне свои два цента из вашего опыта, или приятное руководство / как вы, возможно, наткнулись.
РЕДАКТИРОВАТЬ: Спасибо за ответы всех, я действительно ценю информацию, передаваемую здесь. Немного неудачно, что весь append()
Все оказалась в центре внимания, это просто означало это в качестве примера. Мой вопрос в основном имел в виду необходимость и использование всех различных реализаций, которые я думаю, было несколько упомянуто в паре ответов.
Трудно выбрать один ответ, как принято, поскольку есть три действительно прочные ответы, каждый из которых способствовал моему пониманию проблемы. Мне придется пойти с Anon, на этот раз у него есть наименьшее количество повторений. Очки (я предполагаю, что он новый на так). Он 15 ответов, которые некоторые из которых действительно хорошо сформулированы, и 0 вопросов задавали. Хороший вклад, который я бы сказал, и что стоит продвигать.
То, что сказал, Колин и Джей также предоставили действительно хорошие ответы и указывали на интересные идеи. Особенно комментарий Джея о Java автоматически упаковывать BufferedWriter
стоил отметить. Спасибо, ребята, ребята, очень ценились!
Решение
То java.io
Классы обычно следуют за рисунком декоратора. Так что пока PrintWriter
не имеет конкретного конструктора, который вы можете захотеть, у него есть конструктор, который требует другого Writer
, Так что вы можете сделать что-то вроде следующего:
FileOutputStream fos = null;
try
{
fos = new FileOutputStream("foo.txt");
PrintWriter out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(fos, "UTF-8")));
// do what you want to do
out.flush();
out.close();
}
finally
{
// quietly close the FileOutputStream (see Jakarta Commons IOUtils)
}
Как сообщает общие примечания, вы всегда хотите обернуть писатель низкого уровня (например, FileWriter
или OutputStreamWriter
) в BufferedWriter
, чтобы минимизировать фактические операции IO. Однако это означает, что вам нужно явно промыть и закрывать внешний писатель, чтобы убедиться, что весь контент написан.
И тогда вам нужно закрыть низкоуровневый писатель в finally
Блок, чтобы убедиться, что вы не утекаете ресурсы.
Редактировать:
Смотря на Mforster.Ответ заставил меня сделать еще один взгляд на API для fileWriter. И я понял, что он не принимает явный набор символов, который очень плохой. Поэтому я отредактировал свой фрагмент кода, чтобы использовать FileOutputStream
завернутый А.Н. OutputStreamWriter
который принимает явный набор символов.
Другие советы
FileWriter
как правило, не приемлемый класс для использования. Это не позволяет вам указать Charset
Чтобы использовать для записи, что означает, что вы застряли любым любым значением по умолчанию платформы, на которой вы работаете. Само собой разумеется, что это делает невозможным последовательно использовать одинаковую черт для чтения и записи текстовых файлов и может привести к поврежденным данным.
А не использовать FileWriter
, Вы должны упаковать FileOutputStream
в ан OutputStreamWriter
. OutputStreamWriter
Позволяет вам указать характер:
File file = ...
OutputStream fileOut = new FileOutputStream(file);
Writer writer = new BufferedWriter(new OutputStreamWriter(fileOut, "UTF-8"));
Использовать PrintWriter
с вышеупомянутым, просто оберните BufferedWriter
в PrintWriter
:
PrintWriter printWriter = new PrintWriter(writer);
Ты мог Также просто используйте PrintWriter
конструктор, который принимает File
И название орфографии:
PrintWriter printWriter = new PrintWriter(file, "UTF-8");
Это работает просто для вашей конкретной ситуации, и на самом деле делает то же самое, что и код выше, но приятно знать, как построить его, обернув различные детали.
Другой Writer
Типы в основном для специализированных применений:
StringWriter
просто А.Writer
что можно использовать для созданияString
.CharArrayWriter
одинаково дляchar[]
.PipedWriter
для трубопровода кPipedReader
.
Редактировать:
Я заметил, что вы прокомментировали еще один ответ о многообразии создания писателя таким образом. Обратите внимание, что есть библиотеки, такие как Гуава Это помогает уменьшить многообразие общих операций. Взять, например, написать String
в файл в определенном уровне. С Гуавой вы можете просто написать:
Files.write(text, file, Charsets.UTF_8);
Вы также можете создать BufferedWriter
так:
BufferedWriter writer = Files.newWriter(file, Charsets.UTF_8);
У PrintWriter не имеет конструктора, который занимает параметр «Добавить», но делает файлWriter. И мне кажется логичным, что это где оно принадлежит. PrintWriter не знает, пишете ли вы в файл, сокет, консоль, строку и т. Д. Что бы было означать «Добавить» на пишет в розетку?
Так что правильный способ сделать то, что вы хотите, это просто:
PrintWriter out=new PrintWriter(new BufferedWriter(new FileWriter(myfile, append)));
Интересная сторона Примечание. Если вы оберните вывод в печати, Java автоматически вставляет буферритр в середине. Но если вы оберните писатель в принципе печати, это не так. Так что ничего не получено, говоря:
PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(myfile))));
Просто уходите из буфераристара и вывозитель, вы все равно получаете их бесплатно. Я понятия не имею, если есть какая-то веская причина несоответствия.
Это правда, что вы не можете указать кодировку символов в файлматрии как Notes Conilind. Я не знаю, что это делает его «неприемлемым». Я почти всегда идеально рад принять кодировку по умолчанию. Может быть, если вы используете язык, отличный от английского, это проблема.
Необходимость обернуть писателей или выводы в слоях, путала меня, когда я впервые начал использовать Java. Но как только вы получаете это, это не имеет большого значения. Вам просто нужно согнуть свой разум в рамки записи. Каждый писатель имеет функцию. Подумайте о том, что я хочу печатать в файл, поэтому мне нужно обернуть файл пилара на принципе. Или я хочу преобразовать выходной поток в писатель, поэтому мне нужен выходной сигнал. И т.п.
Или, может быть, вы просто привыкли к те, которые вы используете все время. Выберите его один раз и помните, как вы это сделали.
Вы можете создать присоединение PrintWriter
так:
OutputStream os = new FileOutputStream("/tmp/out", true);
PrintWriter writer = new PrintWriter(os);
Редактировать: Пост Анона правильно оба используя BufferedWriter
между между ними и указанием кодирования.