Лекция 05. Р’РІРѕРґ/вывод ####################################################################################### Введение =========================================================== Классификация Р’Р’ `````````````````````````````````````````````````````````` РџРѕРґ РІРІРѕРґРѕРј/выводом понимают часть стандартной библиотеки пакетов, предоставляющей средства для обмена информацией между устройствами РІРІРѕРґР°/вывода, Р° также файлами. РћСЃРЅРѕРІРЅРѕР№ абстракцией РІ этом процессе является **поток**. Потоки РјРѕРіСѓС‚ быть **буферизированные** Рё **небуферизированные**. Первые используют промежуточные хранилища (буферы), Р° вторые - нет. Также потоки РјРѕРіСѓС‚ быть **байтовые** Рё **символьные**. Первые рассматривают данные как наборы байт, вторые умеют работать СЃ данными, как СЃ символами. Рто важно РїСЂРё использование многобайтных РєРѕРґРёСЂРѕРІРѕРє. Рассмотрим потоки применительно Рє трем областям: * Низкоуровневый РІРІРѕРґ/вывод. * Консольный РІРІРѕРґ/вывод. * Файловый РІРІРѕРґ/вывод. Stream `````````````````````````````````````````````````````````` Р’Рѕ главе иерархии **байтовых** потоков РІРІРѕРґР°/вывода лежат #. **InputStream** - абстрактный поток РІРІРѕРґР°. #. **OutputStream** - абстрактный поток вывода. Р’Рѕ главе иерархии **символьных** потоков РІРІРѕРґР°/вывода лежат #. **Reader** - абстрактный поток РІРІРѕРґР°. #. **Writer** - абстрактный поток вывода. Байтовые потоки `````````````````````````````````````````````````````````` Абстрактный класс **InputStream** .. code-block:: java //Читает 1 байт РёР· РІС…. потока. Результат РІ младшем байте. public abstract int read() throws IOException //Читает послед-ть байт РІ массив b[ ]. // Возвращает РєРѕР»-РІРѕ прочитанных байт или -1. public int read (byte[ ] b) throws IOException //Заполняет массив СЃ указанного байта, //читает РЅРµ более len символов public int read (byte[ ] b, int off, int len) throws IOException // пропускает n байтов РІ потоке public long skip (long n) throws IOException // количество доступных байтов int available () void close () OutputStream `````````````````````````````````````````````````````````` .. code-block:: java // Записывает 1 байт РІ выходной поток. public abstract void write (int b) throws IOException // Записывает РІ поток массив байт public void write (byte[ ] b) throws IOException // Записывает часть массива РІ поток // (len элементов начиная СЃ элемента off) public void write (byte[ ] b, int off, int len) throws IOException //Немедленно выталкивает РёР· буфера РІ поток //РІСЃРµ что накоплено РІ буфере. public void flush() throws IOException //Закрывает поток. public void close() throws IOException Низкоуровневый РІРІРѕРґ/вывод =========================================================== ByteArrayInputStream `````````````````````````````````````````````````````````` **ByteArrayInputStream** – это реализация РІС…РѕРґРЅРѕРіРѕ потока, РІ котором РІ качестве источника используется массив типа **byte**. РЈ этого класса РґРІР° конструктора, каждый РёР· которых РІ качестве первого параметра требует байтовый массив. .. code-block:: java ByteArrayInputStream(byte array[ ]) ByteArrayInputStream(byte array[ ], int start, int numBytes) .. code-block:: java import java.io.*; public class Program { public static void main(String[] arg) { byte [] arr={1,2,3,14,14,16,17,81,82,83}; ByteArrayInputStream in=new ByteArrayInputStream(arr); ByteArrayOutputStream out=new ByteArrayOutputStream(); System.out.println(in.available()); int b; while((b=in.read())!=-1) out.write(b); out.write(10); byte [] c=out.toByteArray(); for(byte i:c) System.out.println((char)i); } } ByteArrayOutputStream `````````````````````````````````````````````````````````` Выходной поток имеет РґРІР° конструктора: .. code-block:: java ByteArrayOutputStream() ByteArrayOutputStream(int size) .. code-block:: java ByteArrayOutputStream baos = new ByteArrayOutputStream(); String text = "Hello Wolrd!"; byte[] buffer = text.getBytes(); try{ baos.write(buffer); } catch(Exception ex){ System.out.println(ex.getMessage()); } // превращаем массив байтов РІ строку System.out.println(baos.toString()); // получаем массив байтов Рё выводим РїРѕ символьно byte[] array = baos.toByteArray(); Метод, записывающий содержимое РѕРґРЅРѕРіРѕ потока РІ РґСЂСѓРіРѕР№: .. code-block:: java public void writeTo(OutputStream out) throws IOException .. code-block:: java byte buf [ ] = {'a','b','c','d'}; ByteArrayOutputStream b = new ByteArrayOutputStream(); b.write(buf); FileOutputStream f = new FileOutputStream("result.txt"); b.writeTo(f); Консольный РІРІРѕРґ/вывод =========================================================== Р’РІРѕРґ ----------------------------------------------------------- Консольный Р’Р’ `````````````````````````````````````````````````````````` Два примера консольного РІРІРѕРґР°: #. **Классический** #. **Современный** .. code-block:: java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { public static void main(String[] args) throws IOException { System.out.println("Hello, enter your name:"); String buf; BufferedReader in=new BufferedReader( new InputStreamReader(System.in)); buf=in.readLine(); System.out.println("Hello, "+buf); } Еще РѕРґРёРЅ вариант: .. code-block:: java import java.io.*; public class ReadConsole { public static void main(String args[]) throws IOException { InputStreamReader cin = null; char c; try { cin = new InputStreamReader(System.in); System.out.println("Enter characters, 'q' to quit."); do { c = (char) cin.read(); System.out.print(c); } while(c != 'q'); }finally { if (cin != null) { cin.close(); } } } } Более современный вариант: .. code-block:: java import java.util.Scanner; public class Main { public static void main(String[] args) { System.out.println("Enter a line:"); String buf; Scanner in = new Scanner(System.in); buf=in.nextLine(); System.out.println("Hello, "+buf); } } .. code-block:: java System.out.println("How old are you?"); int age=0; try { age=Integer.parseInt(in.readLine()); } catch(NumberFormatException ex) { System.out.println("Wrong age!"); System.exit(1); } System.out.printf("Good age %d",age); } } Вывод ----------------------------------------------------------- Консольный Р’Р’ `````````````````````````````````````````````````````````` Рассмотрим методы, используемые СЃ **System.out**: #. **print()** - печать строки без перевода РєСѓСЂСЃРѕСЂР° #. **println()** - печать строки СЃ переводом РєСѓСЂСЃРѕСЂР° #. **printf()** - печать строки СЃ форматированием .. code-block:: java int value=5; System.out.println("Отлично - это "+value); System.out.printf("%d - отличная оценка\n",value); .. code-block:: java import java.util.Date; public class PrintfDemo { public static void main(String[] args) { System.out.println(new Date()); } } Результат: **Thu Mar 23 18:11:50 MSK 2017** Печать текущего РіРѕРґР°: .. code-block:: java import java.util.Date; public class PrintfDemo { public static void main(String[] args) { System.out.printf("%tY\n",new Date()); } } Файловый РІРІРѕРґ/вывод =========================================================== Работа СЃ файлами `````````````````````````````````````````````````````````` Для работы СЃ файлами применяются различные потоки * **FileInputStream,FileOutputStream** - байтовые потоки * **FileReader,FileWriter** - символьные потоки Создание файлового объекта: .. code-block:: java File f = new File("1.txt"); Файловый объект может использоваться как параметр РїСЂРё создании потоков. Байтовые потоки ----------------------------------------------------------- FileInputStream `````````````````````````````````````````````````````````` Рассмотрим работу СЃ файлами СЃ помощью **FileInputStream** .. code-block:: java FileInputStream(String name) throws FileNotFoundException FileInputStream (File file) throws FileNotFoundException Р’ классе **FileInputStream** переопределяется большая часть методов класса **InputStream** (РІ С‚.С‡. абстрактный метод **read()** ). РљРѕРіРґР° создается объект класса **FileInputStream**, РѕРЅ одновременно СЃ этим открывается для чтения. .. code-block:: java import java.io.*; public class FilesApp { public static void main(String[] args) { try { FileInputStream fin=new FileInputStream("note.txt") System.out.println("Размер файла: " + fin.available() + " байт(Р°)"); int i=-1; while((i=fin.read())!=-1){ System.out.print((char)i); } } catch(IOException ex){ System.out.println(ex.getMessage()); } } } .. code-block:: java byte[] buffer = new byte[fin.available()]; // считываем файл РІ буфер fin.read(buffer, 0, fin.available()); System.out.println("Содержимое файла:"); for(int i=0; i<buffer.length;i++){ System.out.print((char)buffer[i]); } FileOutputStream `````````````````````````````````````````````````````````` Класс **FileOutputStream** РјРѕР¶РЅРѕ применять для записи байтов РІ файл. РЈ класса **FileOutputStream** есть 3 конструктора: .. code-block:: java FileOutputStream (String filePath) throws FileNotFoundException FileOutputStream (File fileObj) throws FileNotFoundException FileOutputStream (String filePath, boolean append) throws FileNotFoundException .. code-block:: java try { FileInputStream source = new FileInputStream("infile.dat"); FileOutputStream dest = new FileOutputStream("outfile.dat"); int c; while ((c = source.read()) != -1) { dest.write(c); } source.close(); dest.close(); } catch (FileNotFoundException ex) {...} Пример работы СЃ РґРІСѓРјСЏ файлами .. code-block:: java import java.io.*; public class FilesApp { public static void main(String[] args) { try { FileOutputStream fos=new FileOutputStream("new.txt"); FileInputStream fin=new FileInputStream("notes.txt"); byte[] buffer = new byte[fin.available()]; // считываем буфер fin.read(buffer, 0, buffer.length); // записываем РёР· буфера РІ файл fos.write(buffer, 0, buffer.length); } catch(IOException ex){ System.out.println(ex.getMessage()); } } } Символьные потоки ----------------------------------------------------------- FileReader `````````````````````````````````````````````````````````` Для работы СЃ символами Рё строками используют **символьные потоки**. Основные методы **FileReader**: * **int read() throws IOException** - чтение одиночного символа. * **int read(char [] c, int offset, int len)** - чтение символов РІ массив. .. code-block:: java ... try { FileReader reader=new FileReader("1.txt"); int c; while((c=reader.read())!=-1) { System.out.print((char)c); } catch(IOException ex) { System.out.println(ex.getMessage()); } } ... Для чтения строк СѓРґРѕР±РЅРѕ использовать буферизированный поток **BufferedReader**: .. code-block:: java File file = new File("..."); FileReader reader = new FileReader(file); BufferedReader breader = new BufferedReader(reader); String line; while ((line=breader.readLine()) != null) { ... } reader.close(); FileWriter `````````````````````````````````````````````````````````` .. code-block:: java import java.io.*; class Random2FileWriter { public static void main(String[] args) throws Exception { Writer file = new FileWriter("random.txt"); int n=(int)(Math.random()*10); String outstr="Number:"+n; file.write(outstr); file.close(); } } Копирование строк: .. code-block:: java BufferedReader in = null; PrintWriter out = null; String line; try { in = new BufferedReader(new FileReader(args[0])); out = new PrintWriter(new FileWriter(args[1])); while ((line = in.readLine()) != null) { out.println(l); }} finally { if (in!= null) { in.close(); } if (out!= null) { out.close(); } } .. code-block:: java Reader reader; Writer writer; try { reader = new FileReader(args[0]); writer = new FileWriter(args[1]); int c = 0; while ((c = reader.read()) >= 0) { writer.write(Character.toUpperCase((char) c)); } reader.close(); writer.close(); } catch(FileNotFoundException ex) {} catch(IOException ex) { } Специальные типы файлов =========================================================== Файлы свойств ----------------------------------------------------------- Properties `````````````````````````````````````````````````````````` РњРѕР¶РЅРѕ использовать файлы для хранения наборов свойств: .. code-block:: java import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Enumeration; import java.util.Properties; public class ReadPropertiesFile { public static void main(String[] args) { try { File file = new File("test.properties"); FileInputStream fileInput = new FileInputStream(file); Properties properties = new Properties(); properties.load(fileInput); fileInput.close(); .. code-block:: java Enumeration enuKeys = properties.keys(); while (enuKeys.hasMoreElements()) { String key = (String) enuKeys.nextElement(); String value = properties.getProperty(key); System.out.println(key + ": " + value); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } Запись файла СЃРѕ свойствами: .. code-block:: java import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Properties; public class WritePropertiesFile { public static void main(String[] args) { try { Properties properties = new Properties(); properties.setProperty("favoriteAnimal", "marmot"); properties.setProperty("favoriteContinent", "Antarctica"); properties.setProperty("favoritePerson", "Nicole"); .. code-block:: java File file = new File("test.properties"); FileOutputStream fileOut = new FileOutputStream(file); properties.store(fileOut, "Favorite Things"); fileOut.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } XML-файлы ----------------------------------------------------------- XML `````````````````````````````````````````````````````````` Р’ более сложных случаях предпочтительно использовать **XML**-файлы. .. code-block:: java import java.io.*; import java.util.Enumeration; import java.util.Properties; public class ReadPropertiesXmlFile { public static void main(String[] args) { try { File file = new File("test.xml"); FileInputStream fileInput = new FileInputStream(file); Properties properties = new Properties(); properties.loadFromXML(fileInput); fileInput.close(); ... .. code-block:: java ... Enumeration enuKeys = properties.keys(); while (enuKeys.hasMoreElements()) { String key = (String) enuKeys.nextElement(); String value = properties.getProperty(key); System.out.println(key + ": " + value); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }}} Запись XML- файла: .. code-block:: java import java.io.* import java.util.Properties; public class WritePropertiesXmlFile { public static void main(String[] args) { try { Properties properties = new Properties(); properties.setProperty("favoriteAnimal", "marmot"); properties.setProperty("favoriteContinent", "Antarctica"); properties.setProperty("favoritePerson", "Nicole"); ... .. code-block:: java ... File file = new File("test.xml"); FileOutputStream fileOut = new FileOutputStream(file); properties.storeToXML(fileOut, "Favorite Things"); fileOut.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }} JSON ----------------------------------------------------------- **JSON (JavaScript Object Notation)** - специальный текстовый формат для обмена данными (чаще всего между клиентом Рё сервером). Рассмотрим пример: .. code-block:: none "students": [ { "id": 100, "fio": "Рванов Рђ.Рђ." }, { "id": 101, "fio": "Петров Р’.Р’." } ] } Для работы СЃ форматом **JSON** существует несколько библиотек. РћРґРЅР° РёР· наиболее распространенных: **json-simple**. .. code-block:: java import java.io.*; import org.json.simple.*; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; public class JSONRead { public static void main(String[] args) { try { File f=new File("students.json"); JSONParser parser=new JSONParser(); FileReader fr = new FileReader(f); .. code-block:: java Object obj=parser.parse(fr); JSONObject js=(JSONObject)obj; JSONArray items=(JSONArray)js.get("students"); for(Object i : items) { System.out.println(((JSONObject)i).get("id")); } } catch (FileNotFoundException ex) { System.out.println(ex.getMessage()); } catch (ParseException ex) { System.out.println(ex.getMessage()); } catch(IOException ex) { System.out.println(ex.getMessage()); } } } Р’РѕРїСЂРѕСЃС‹ для самоконтроля =============================================