Когда использовать, какой писатель подкласс в Java; общие практики

StackOverflow https://stackoverflow.com/questions/4069698

  •  28-09-2019
  •  | 
  •  

Вопрос

Я всегда слегка путался с количеством различных реализаций 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 между между ними и указанием кодирования.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top