— Привіт, Аміго!

— Привіт, Еллі!

— Сьогодні я хочу тобі розповісти про класи StringReader і StringWriter. Принципово нового тут тобі буде мало, але іноді ці класи бувають дуже корисними. І, як мінімум, я хочу, щоб ти знав, що вони є.

Ці класи – це найпростіші реалізації абстрактних класів Reader та Writer. І практично аналоги FileReader та FileWriter. Але, на відміну від них, вони працюють не з даними у файлі на диску, а з рядком (String) Java-машини, що знаходиться в пам'яті.

— А навіщо такі класи потрібні?

— Іноді потрібні. StringReader – це, фактично, перехідник між класом String і Reader. А StringWriter – це рядок, який успадкований від Writer. М-так. Сама бачу, що пояснення не надто. Давай краще спочатку розглянемо пару прикладів.

Наприклад, ти хочеш перевірити, як працює твій метод, який має вичитувати дані з переданого до нього об'єкта Reader. Ось як це можна зробити:

Читання з об'єкта reader:
public static void main ( String[] args) throws Exception
{
 String test = "Hi!\n My name is Richard\n I'm a photographer\n" ;

 //це рядок – ключова: ми «перетворили» рядок на Reader
 StringReader reader = new StringReader(test);

 executor(reader);
}

public static void executor(Reader reader) throws Exception
{
 BufferedReader br = new BufferedReader(reader);
String line;
while ((line = br.readLine()) != null)
 {
  System.out.println(line);
 }
}

— Тобто. ми просто взяли рядок, обернули його в StringReader і передали замість об'єкта Reader? І з неї все читатиметься, як і треба?

— Ага. Гм. А в цьому є сенс. А тепер перевіримо, як працюють методи StringWriter. Для цього ускладнимо приклад. Тепер він не просто читатиме рядки, і виводитиме їх на екран, а розгортатиме їх задом наперед і виводитиме в об'єкт writer. Приклад:

Читання з об'єкта reader та запис в об'єкт writer:
public static void main (String[] args) throws Exception
{
 //цей рядок повинен буде прочитати Reader
 String test = "Hi!\n My name is Richard\n I'm a photographer\n" ;
 //Загортаємо рядок у StringReader
 StringReader reader = новий StringReader(test);

 //Створюємо об'єкт StringWriter
 StringWriter writer = new StringWriter();

 //переписуємо рядки з Reader у Writer, попередньо розгорнувши їх
 executor(reader, writer);

 //отримуємо текст, що був записаний у Writer
 String result = writer.toString();

 //виводимо отриманий з Writer'а текст на екран
 System.out.println("Результат: "+result);
}

public static void executor(Reader reader, Writer writer) throws Exception
{
 BufferedReader br = new BufferedReader(reader);
String line;

  //читаємо рядок з Reader'а

while ((line = br.readLine()) != null)
 {
  // Розгортаємо рядок задом наперед
  StringBuilder sb = new StringBuilder(line) ;
  String newLine = sb.reverse().toString();

  // пишемо рядок у Writer
  writer.write(newLine);
 }
}

Ми створили об'єкт StringWriter, усередині якого є рядок, в якому зберігається все, що в цей writer пишуть. А щоб її отримати, треба лише викликати методtoString().

— Гм. Якось усе надто просто виходить. Метод executor працює з об'єктами потокового введення reader і writer, а в методі main ми працюємо вже з рядками.

Все так просто?

— Ага. Щоб перетворити рядок у Reader досить написати:

Створення Reader із String
String s = "data";
Reader reader = новий StringReader(s);

А перетворити StringWriter до рядка ще простіше:

Отримання String з Writer
Writer writer = New StringWriter();
/*тут пишемо купу даних у writer */
String result = writer. toString();

— Відмінні класи, як на мене. Дякую за оповідання, Еллі.