CodeGym /Java курс /All lectures for BG purposes /Изходни потоци

Изходни потоци

All lectures for BG purposes
Ниво , Урок
На разположение

1. OutputStreamклас

Наскоро проучихме входните потоци. Време е да поговорим за изходните потоци.

Класът OutputStreamе родителският клас за всички класове, които поддържат byteов изход. Това е абстрактен клас, който не прави нищо сам, но има класове наследници за всеки случай.

Звучи изключително сложно. Казано по-просто, този клас оперира с byteове, а не, например, със знаци or други типове данни. А фактът, че е абстрактен, означава, че обикновено не го използваме, а по-скоро един от неговите потомствени класове. Например FileOutputStreamи други подобни.

Но обратно към OutputStreamкласа. Този клас има методи, които всички негови класове-потомци трябва да изпълняват. Ето основните от тях:

Методи Описание
void write(int b)
Записва един byte (не int) в потока.
void write(byte[] buffer)
Записва масив от byteове в потока
void write(byte[] buffer, off, len)
Записва част от масив от byteове в потока
void flush()
Записва всички данни, съхранени в буфера, в потока
void close()
Затваря потока

Когато създавате обект от клас, който наследява InputStream, обикновено посочвате обект източник, InputStreamот който чете данни. Когато създавате обект от клас, който наследява OutputStream, обикновено посочвате и целевия обект or поток, в който ще се записват данни.

Нека прегледаме накратко всички методи на OutputStreamкласа:

write(int b)метод

Този метод записва един byte (не int) в изходния поток. Предадената стойност се преобразува в byte и първите три byteа на int се отхвърлят.

write(byte[] buffer)метод

Записва дадения масив от byteове в изходния поток. Това е.

write(byte[] buffer, int offset, int length)метод

Записва част от предадения масив от byteове в изходния поток. Променливата offset показва индекса на първия елемент от масива и lengthе дължината на подмножеството, което трябва да се запише.

flush()метод

Методът flush()се използва, за да принуди всички данни, потенциално буферирани в текущия поток, да бъдат записани в целевия поток. Това е уместно при използване на буфериране и/or множество обекти на поток, подредени във верига.

close()метод

Записва всички незаписани данни в целевия обект. Методът close()не трябва да се извиква, ако използвате try-with-resourcesблок.

Пример за копиране на файл

Код Забележка
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileInputStream input = new FileInputStream(src);
FileOutputStream output = new FileOutputStream(dest))
{
   byte[] buffer = new byte[65536]; // 64Kb
   while (input.available() > 0)
   {
      int real = input.read(buffer);
      output.write(buffer, 0, real);
   }
}



InputStreamза четене от файл
OutputStreamза запис във файл

Буфер, в който ще четем данните
Докато има данни в потока

Четене на данни в буфера
Записване на данните от буфера във втория поток

2. Writerклас

Класът Writerе абсолютно същият като OutputStreamкласа, но само с една разлика още веднъж: работи със знаци ( char) instead of с byteове.

Това е абстрактен клас: не можете да създавате обекти от Writerкласа. Основната му цел е да бъде общ родителски клас за стотици наследствени класове и да им даде общи методи за работа с потоци от символи.

Методи на Writerкласа (и всички негови потомствени класове):

Методи Описание
void write(int b)
Записва един символ (не int) в потока.
void write(char[] buffer)
Записва масив от знаци в потока
void write(char[] buffer, off, len)
Записва част от масив от знаци в потока
void write(String str)
Записва низ в потока
void write(String str, off, len)
Записва част от низ в потока
void flush()
Записва всички данни, съхранени в буфера, в потока
void close()
Затваря потока

Методите са много подобни на методите на OutputStreamкласа, но работят със символи instead of с byteове.

Описание на методите:

write(int b)метод

Този метод записва един знак ( char— не int) в изходния поток. Предадената стойност се преобразува в a charи първите два byteа се отхвърлят.

write(char[] buffer)метод

Записва дадения масив от знаци в изходния поток.

write(char[] buffer, int offset, int length)метод

Записва част от предадения масив от знаци в изходния поток. Променливата offsetпоказва индекса на първия елемент от масива и lengthе дължината на подмножеството, което трябва да се запише.

write(String str)метод

Записва дадения низ в изходния поток.

write(String str, int offset, int length)метод

Записва част от дадения низ в изходния поток: низът се преобразува в масив от знаци. Променливата offsetпоказва индекса на първия елемент от масива и lengthе дължината на подмножеството, което трябва да се запише.

flush()метод

Методът flush()се използва, за да принуди всички данни, потенциално буферирани в текущия поток, да бъдат записани в целевия поток. Това е уместно при използване на буфериране и/or множество обекти на поток, подредени във верига.

close()метод

Записва всички незаписани данни в целевия обект. Методът close()не трябва да се извиква, ако използвате try-with-resourcesблок.

Пример за програма, която копира текстов файл:

Код Забележка
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileReader reader = new FileReader(src);
FileWriter writer = new FileWriter(dest))
{
   char[] buffer = new char[65536]; // 128Kb
   while (reader.ready())
   {
      int real = reader.read(buffer);
      writer.write(buffer, 0, real);
   }
}



Readerза четене от файл
Writerза запис във файл

Буфер, в който ще четем данните
Докато има данни в потока

Четене на данни в буфер
Записване на данните от буфера във втория поток

StringWriterклас

Има още един интересен клас, който наследява Writerкласа: той се нарича StringWriter. Той съдържа променлив низ — StringBufferобект. И всеки път, когато "пишете" нещо на StringWriterобекта, текстът просто се добавя към неговия вътрешен буфер.

Пример:

Код Забележка
StringWriter writer = new StringWriter();
writer.write("Hello");
writer.write(String.valueOf(123));

String result = writer.toString();
StringWriterСъздава се целеви символен поток ( )
Низ се записва в буфера вътре StringWriter
Низ се записва в буфера вътре StringWriter

Преобразуване на съдържанието на обект в низ

В този случай StringWriterкласът е по същество обвивка над StringBufferкласа, но StringWriterкласът е потомък на Writerкласа поток и може да се използва във вериги от обекти на поток. Това е доста полезно свойство на практика.



3. PrintStreamклас

Класовете на изходния поток могат също да бъдат поставени във верига с междинни потоци, които записват данни в целевия поток, който им се предава. Общият изглед на взаимодействието на тези потоци изглежда така:

Клас PrintStream

Най-интересният и многофункционален от всички междинни изходни потоци е PrintStream. Има десетки методи и цели 12 конструктора.

Класът PrintStreamнаследява FilterOutputStreamкласа, който наследява OutputStream. Това означава, че PrintStreamкласът има всички методи на родителските класове в допълнение към своите собствени методи . Ето най-интересните от тях:

Методи Описание
void print(obj)
Преобразува подавания обект в низ и го извежда към целевия поток.
void println(obj)
Преобразува подавания обект в низ и го извежда към целевия поток. Добавя нов ред в края
void println()
Извежда знак за нов ред към целевия поток
PrintStream format(String format, args...)
Конструира и извежда низ въз основа на форматиращия низ и предадените аргументи; подобно на String.format()метода

И къде са тези десетки методи, ще попитате?

Е, има много варианти на print()и println()методи с различни параметри. Те могат да бъдат обобщени в тази table.

Няма да се потапяме в тези методи, защото вече ги познавате добре. Можете ли да познаете Howво имам предвид?

помниш System.out.println()ли Но може да се напише в два реда:

Код Конзолен изход
PrintStream stream = System.out;
stream.println("Hello!");
Hello!

Нашата любима команда е извикване на метода на статичната променлива на класа. И типът на тази променлива е .System.out.println()println()outSystemPrintStream

В много нива на CodeGym и в почти всяка задача вие сте извиквали методи на PrintStreamкласа, без дори да го знаете!

Практическа употреба

Java има този интересен клас, наречен ByteArrayOutputStream, който е динамично нарастващ byteов масив, който наследява OutputStream.

Обект ByteArrayOutputStreamи PrintStreamобект могат да бъдат свързани по следния начин:

Код Описание
ByteArrayOutputStream baos = new ByteArrayOutputStream();

try(PrintStream stream = new PrintStream(baos))
{
   stream.println("Hello");
   stream.println(123);
}

String result = baos.toString();

System.out.println(result);
Създайте буфер за запис в паметта

Увийте буфера в PrintStreamобект

Запишете данни в конзолата



Преобразувайте масива в низ!

Конзолен изход:
Hello!
123

Коментари
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION