SlideShare une entreprise Scribd logo
1  sur  51
Консольный ввод-вывод
Байтовые и символьные потоки
Аналогично языку С++ ввод/вывод в
языке Java выполняется с
использованием потоков. Поток
ввода/вывода - это некоторый
условный канал, по которому
отсылаются и получаются данные.
В Java 2 реализованы 2 типа потоков: байтовые и символьные.
Байтовые потоки предоставляют удобные средства для
обработки, ввода и вывода байтов или других двоичных
объектов. Символьные потоки используются для обработки,
ввода и вывода символов или строк в кодировке Unicode.
Все классы для консольного I/O – пакет java.io: import java.io.*;
1
Консольный ввод-вывод
Байтовые потоки

2
Консольный ввод-вывод
Байтовые потоки.
Абстрактный класс InputStream.
public abstract int read()
throws IOException

Читает 1 байт из вх. потока.
Результат в младшем байте.

public int read (byte[ ] b)
throws IOException

Читает послед-ть байт в
массив b[ ]. Возвращает колво прочитанных байт или -1.

public int read (byte[ ] b,
int off, int len) throws
IOException

Заполняет массив с
указанного байта, читает не
более len символов

public long skip (long n)
throws IOException

Пропускает n байт в потоке

int available ()

Возвращает кол-во
доступных байт в потоке.

void close ()

Закрывает поток ввода.
3
Консольный ввод-вывод
Байтовые потоки.
Класс FileInputStream.
FileInputStream(String name) throws FileNotFoundException
FileInputStream (File file) throws FileNotFoundException
В классе FileInputStream переопределяется большая часть
методов класса Input-Stream (в т.ч. абстрактный метод
read() ). Когда создается объект класса FileInputStream, он
одновременно с этим открывается для чтения.

4
Консольный ввод-вывод
Байтовые потоки.
Класс FileInputStream.
import java.io.*;
System.out.println("Still Available: " + fp.available());
System.out.println("Total Still Available: " + fp.available());
class FileInputTest
System.out.println("Skipping another 1/4: skip()");
System.out.println("Reading the next 1/4: read(b[ ])");
{public static void main(String args[ ]) throws Exception
fp.skip(size/4);
byte b[ ] = new byte[size/4];
{int size;
System.out.println("Still Available: " + fp.available());
if (fp.read(b) == -1)
InputStream fp = new FileInputStream("FileInputTest.java");
System.out.println("Reading 1/8 into the end of array");
{System.out.println("End of File"); }
sizeif=(f1.read(b, b.length-size/8, size/8) == -1)
fp.available();
for (int i=0; i < size/4; i++)
System.out.println("Total Available Bytes: " + size);
{System.out.println("End of File”); }
{System.out.print((char) b[i]); }
System.out.println("First 1/4Available: "read()");
System.out.println("Still of the file: + f1.available());
for (int i=0; i < }
fp.close(); size/4; i++)
{System.out.print((char) fp.read()); }
}

5
Консольный ввод-вывод
Байтовые потоки.
Класс ByteArrayInputStream.
ByteArrayInputStream – это реализация входного потока, в
котором в качестве источника используется массив типа
byte. У этого класса два конструктора, каждый из которых
в качестве первого параметра требует байтовый массив.
ByteArrayInputStream(byte array[ ])
ByteArrayInputStream(byte array[ ], int start, int numBytes)

6
Консольный ввод-вывод
Байтовые потоки.
Класс ByteArrayInputStream.
import java.io.*;
class ByteArrayTest
{public static void main(String args [ ]) throws IOException
{byte b[ ] = {0,1,2,3,4,5,6,7,8,9};
ByteArrayInputStream input1 =
new ByteArrayInputStream(b);
ByteArrayInputStream input2 =
new ByteArrayInputStream(b,0,3);
}
}
7
Консольный ввод-вывод
Байтовые потоки.
Абстрактный класс OutputStream.
public abstract void write (int
b) throws IOException

Записывает 1 байт в выходной
поток.

public void write (byte[ ] b)
throws IOException

Записывает в поток массив байт

public void write (byte[ ] b, int
off, int len)
throws IOException

Записывает часть массива в
поток (len элементов начиная с
элемента off)

public void flush()
throws IOException

Немедленно выталкивает из
буфера в поток все что накоплено
в буфере.

public void close()
throws IOException

Закрывает поток.

8
Консольный ввод-вывод
Байтовые потоки.
Класс FileOutputStream.
Класс FileOutputStream можно применять для записи байтов в
файл. У класса FileOutputStream есть 3 конструктора:
FileOutputStream (String filePath) throws FileNotFoundException
FileOutputStream (File fileObj) throws FileNotFoundException
FileOutputStream (String filePath, boolean append)
throws FileNotFoundException

- filePath – полное имя файла,
- fileObj – объект типа File, который описывает файл
- append (=true – добавление информации в существующий файл)
9
Консольный ввод-вывод
Байтовые потоки.
Класс FileOutputStream.
try
{FileInputStream Source = new FileInputStream("infile.dat");
FileOutputStream Dest = new FileOutputStream("outfile.dat");
int c;
while ((c = Source.read()) != -1)
{Dest.write(c); }
}
catch (FileNotFoundException ex)
{… }
finally
{Source.close(); Dest.close(); }

10
Консольный ввод-вывод
Байтовые потоки.
Класс ByteArrayOutputStream.
ByteArrayOutputStream( ); - 32 байта
ByteArrayOutputStream(int numBytes);
Метод, записывающий содержимое одного потока в другой:
public void writeTo(OutputStream out) throws IOException
byte buf [ ] = {‘a’,’b’,’c’,’d’};
ByteArrayOutputStream b = new ByteArrayOutputStream();
b.write(buf);
FileOutputStream f = new FileOutputStream(“result.txt”);
b.writeTo(f);
11
Консольный ввод-вывод
Символьные потоки.

В Java символы хранятся в кодировке Unicode.
Символьный поток I/O автоматически транслирует
Символы между форматом Unicode и локальной
кодировкой, пользовательского ПК.

12
Консольный ввод-вывод
Символьные потоки.

13
Консольный ввод-вывод
Символьные потоки.
Методы классов Reader и Writer аналогичны методам
классов InputStream и OutputStream с той разницей,
что все аргументы типа byte заменены на аргументы
типа char.
Классы CharArrayReader и CharArrayWriter
соответствуют классам ByteArrayInputStream и
ByteArrayOutputStream с той же разницей.
Классы FileReader и FileWriter являются символьными
версиями потоковых классов FileInputStream и
FileOutputStream.
14
Консольный ввод-вывод
Символьные потоки.
Классы InputStreamReader и OutputStreamWriter –
переходники между байтовыми и символьными
потоками. Байтовый поток используется для
физического ввода-вывода, а символьный поток
преобразует байты в символы с учетом
кодировки.
InputStreamReader (InputStream obj)
OutputStreamWriter (OutputStream out)
15
Консольный ввод-вывод
Буферизованный ввод-вывод.
В библиотеке Java имеются также буферизованные потоки I/O.
Для буферизованных потоков операции чтения и записи
происходят с буфером, находящимся в памяти.
Когда буфер пуст выполняется реальная операция чтения из
потока, когда буфер полон – реальная операция записи в поток.
Буферизация может быть добавлена к любому байтовому либо
символьному потоку с помощью специальных классов
«оболочек» (“wrappers”). При этом конструктору
буферизованного потока передается не буферизованный поток.
16
Консольный ввод-вывод
Буферизованный ввод-вывод.
Буферизованные потоки I/O:
BufferedInputStream, BufferedOutputStream байтовые
BufferedReader, BufferedWriter – символьные
Конструкторы:
BufferedInputStream(InputStream in)
BufferedOutputStream(OutputStream out)
BufferedReader(Reader in)
BufferedWriter(Writer out)

17
Консольный ввод-вывод
Пример организации консольного
ввода-вывода
В пакете java.lang есть класс с именем System.
В классе System определены три переменные:
public static InputStream in;
public static PrintStream out;
public static PrintStream err;
System.out и System.err – байтовые потоки, эмулирующие
поддержку локального character set !
System.in – байтовый поток !
18
Консольный ввод-вывод
Пример организации консольного
ввода
int a;
String str;
BufferedReader br =
= new BufferedReader( new InputStreamReader( System.in ) );
Буферизованный

Символьный поток

Байтовый поток

поток ввода

ввода

ввода

str = br.readLine();
a = Integer.parseInt(str);
19
Консольный ввод-вывод
Пример организации консольного
вывода
Класс PrintStream содержит методы print()
и println() для всех базовых типов данных.
Т.о. для консольного вывода надо вызвать System.out.print()
или System.out.println()
System.out.println (“Значение а = ” +а);
System.out.print (str);

20
Консольный ввод-вывод
Класс Scanner начиная с JSDK 1.5
import java.util.Scanner;
…
Scanner sc = new Scanner(System.in);
…
System.out.println(“Input a:”);
int a = sc.nextInt();
System.out.println(“Input str:”);
String str = sc.next();

Подробнее см.
http://docs.oracle.com/javase/1.5.0/docs/api/index.html?java/util/Scanner.html
21
Консольный ввод-вывод
Класс File
Класс File представляет имя файла, но не
сам файл (если файл не существует, он не
создается, если существует с ним можно
проводить производить операции через
объект File) !
Конструкторы:
public File(String pathname)
public File(String pathname, String filename)
public File (File parent, String child)
22
Консольный ввод-вывод
Класс File
public boolean exists()

Существует ли файл?

public boolean canRead()

Возможен ли доступ на чтение?

public boolean canWrite()

Возможен ли доступ на запись

public boolean isHidden()

Является ли файл скрытым?

public boolean isFile()

Файл?

public boolean isDirectory()

Каталог?

public boolean delete()

Удаляет файл, если он
существует. Каталог удаляется
только если он пуст.

public String[ ] list()

Возвращает список файлов в
каталоге
23
Консольный ввод-вывод
Класс File

public boolean mkdir()

Создает пустой каталог

public boolean renameTo
(File newName)

Переименование файла

public boolean setReadOnly()

Устанавливает атрибут ReadOnly

24
Сериализация в Java
Что такое сериализация?
Сериализация это процесс сохранения
состояния объекта в последовательность
байт;
десериализация это процесс восстановления
объекта из этих байт. Java Serialization API
предоставляет стандартный механизм для
создания сериализуемых объектов.

25
Сериализация в Java
Для чего нужна сериализация?
В Java всё представлено в виде объектов.
Если двум компонентам Java необходимо
общаться друг с другом, то им необходим
механизм для обмена данными.
Следовательно, должен быть универсальный
и эффективный протокол передачи объектов
между компонентами. Сериализация создана
для этого, и компоненты Java используют этот
протокол для передачи объектов.
26
Сериализация в Java
3 механизма сериализации
Сериализация

1) используя протокол по
умолчанию
2) модифицируя протокол по
умолчанию
3) создавая свой собственный
протокол

27
Сериализация в Java
1) Протокол по умолчанию
Чтобы объект стал сериализуемым,
необходимо, чтобы он реализовывал
интерфейс java.io.Serializable.
Интерфейс Serializable это интерфейсмаркер; в нём не задекларировано ни
одного метода. Но он говорит
сериализующему механизму, что класс
может быть сериализован.

28
Сериализация в Java
1) Протокол по умолчанию.
Сохранение объекта
import java.io.Serializable;
import java.util.Date;
import java.util.Calendar;
public class PersistentTime implements Serializable {
private Date time;
public PersistentTime() {
time = Calendar.getInstance().getTime();
}
public Date getTime() {
return time;
}
}
29
Сериализация в Java
1) Протокол по умолчанию.
Сохранение объекта
Для сохранения объекта как последовательности байт
используется класс java.io.ObjectOutputStream
Этот класс является фильтрующим потоком (filter
stream) - он окружает низкоуровневый поток байтов
(называемый узловым потоком (node stream)) и
предоставляет нам поток сериализации. Узловые
потоки могут быть использованы для записи в файловую
систему, сокеты и т.д. Это означает, что можно,
например,
передавать разложенные на байты объекты по сети и
затем восстанавливать их на других компьютерах!30
Сериализация в Java
1) Протокол по умолчанию.
Сохранение объекта
import java.io.ObjectOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FlattenTime {
public static void main(String [] args) {
String filename = "time.ser";
PersistentTime time = new PersistentTime();
FileOutputStream fos = null;
ObjectOutputStream out = null;

31
Сериализация в Java
1) Протокол по умолчанию.
Сохранение объекта
try {
fos = new FileOutputStream(filename);
out = new ObjectOutputStream(fos);
out.writeObject(time);

//сериализация

out.close();
}
catch(IOException ex) {
ex.printStackTrace();
}
}
}

32
Сериализация в Java
1) Протокол по умолчанию.
Восстановление объекта
Для восстановления объекта используется метод
readObject() класса java.io.ObjectInputStream. Метод
считывает последовательность байтов и создает объект,
полностью повторяющий оригинал. Поскольку readObject()
может считывать любой сериализуемый объект,
необходимо его присвоение соответствующему типу. Т.о.,
из
системы, в которой происходит восстановление объекта,
должен быть доступен файл класса. Т.е. при сериализации
не сохраняется ни файл класса объекта, ни его методы,
сохраняется лишь состояние объекта.

33
Сериализация в Java
1) Протокол по умолчанию.
Восстановление объекта
import java.io.ObjectInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Calendar;
public class InflateTime {
public static void main(String [] args) {
String filename = "time.ser";
PersistentTime time = null;
FileInputStream fis = null;
ObjectInputStream in = null;
34
Сериализация в Java
1) Протокол по умолчанию.
Восстановление объекта
try {
fis = new FileInputStream(filename);
in = new ObjectInputStream(fis);
time = (PersistentTime)in.readObject(); //десериализация
in.close();
}
catch(IOException ex) {
ex.printStackTrace();
}
catch(ClassNotFoundException ex) {
ex.printStackTrace();
}

35
Сериализация в Java
1) Протокол по умолчанию.
Восстановление объекта
// распечатать восстановленное время
System.out.println("Время сохранения: " + time.getTime());
System.out.println();
// распечатать текущее время
System.out.println("Текущее время: " +
Calendar.getInstance().getTime());
}
}

36
Сериализация в Java
1) Протокол по умолчанию.
Ограничения сериализации
1) Если в состав сериализуемого класса A входит поле класса
B, то класс B тоже должен быть сериализуемым. Иначе в
процессе сериализации возникнет исключение
NotSerializableException .
2) В процессе сериализации/ десериализации не участвуют
статические поля класса, поскольку они фактически
являются не полями объектов (экземпляров класса), а
полями класса в целом.
3) Влияние наследования на сериализацию. Пусть класс A
объявлен, как сериализуемый. От него унаследован класс
B, для которого не указано implements Serializable . От B
порожден класс C - сериализуемый. Тогда при
сериализации будут сохранены все поля классов A и C , но
не B .
37
Сериализация в Java
1) Протокол по умолчанию.
Несериализуемые поля
Класс java.lang.Object не реализует Serializable,
поэтому не все объекты Java могут быть
автоматически сохранены.
Например, некоторые системные классы, такие
как Thread, OutputStream и его подклассы, и
Socket - не сериализуемые.
Причина: сериализация таких классов
бессмысленна.

38
Сериализация в Java
1) Протокол по умолчанию.
Несериализуемые поля
Проблема: есть класс, который содержит
экземпляр Thread? Можем ли мы в этом случае
сохранить объект такого типа?
Решение: мы имеем возможность сообщить
механизму сериализации о своих намерениях,
пометив объект Thread нашего класса как
несохраняемый - transient.

39
Сериализация в Java
1) Протокол по умолчанию.
Несериализуемые поля
import java.io.Serializable;
public class PersistentAnimation implements Serializable, Runnable {
transient private Thread animator;
private int animationSpeed;
public PersistentAnimation(int animationSpeed) {
this.animationSpeed = animationSpeed;
animator = new Thread(this);
animator.start();
}
public void run() { … }
}
40
Сериализация в Java
2) Модификация протокола по
умолчанию.
Проблема: как перезапустить анимацию?
Когда мы создаем объект при помощи new,
конструктор объекта вызывается только при
создании нового экземпляра. Читая объект
методом readObject() мы не создаем нового
экземпляра, мы просто восстанавливаем
сохраненный объект. В результате
анимационный поток запустится лишь
однажды, при первом создании экземпляра этого
объекта.

41
Сериализация в Java
2) Модификация протокола по
умолчанию.
Решение:
private void writeObject(ObjectOutputStream out)
throws IOException;
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException;
Виртуальная машина при вызове
соответствующего метода автоматически
проверяет, не были ли они объявлены в классе
объекта.

42
Сериализация в Java
2) Модификация протокола по
умолчанию.
import java.io.Serializable;
public class PersistentAnimation implements Serializable, Runnable {
transient private Thread animator;
private int animationSpeed;
public PersistentAnimation(int animationSpeed) {
this.animationSpeed = animationSpeed;
startAnimation();
}
public void run() { … }

43
Сериализация в Java
2) Модификация протокола по
умолчанию.
private void startAnimation() {
animator = new Thread(this);
animator.start();
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject(); //мы не меняем нормальный процесс
}
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
in.defaultReadObject();

//мы лишь дополняем его

startAnimation();
}

44
Сериализация в Java
2) Модификация протокола по
умолчанию. Запрет сериализации для
класса.
Проблема:
class A implements Serializable {
…
}
class B extends A {
…
}
Как запретить сериализацию для класса В?

45
Сериализация в Java
2) Модификация протокола по
умолчанию. Запрет сериализации для
класса.
Решение:
private void writeObject(ObjectOutputStream out) throws IOException
{
throw new NotSerializableException(“Non serializable class!");
}
private void readObject(ObjectInputStream in) throws IOException
{
throw new NotSerializableException (“Non serializable class!");
}
46
Сериализация в Java
3) Создание собственного протокола
Вместо реализации интерфейса Serializable, можно
реализовать интерфейс Externalizable, который содержит
два метода:
public void writeExternal(ObjectOutput out) throws
IOException;
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException;
Для создания собственного протокола надо переопределить
эти методы. Здесь ничего не делается автоматически.
Это наиболее сложный, но и наиболее контролируемый
способ.

47
Сериализация в Java
Кэширование объектов в потоке
Проблема: Рассмотрим ситуацию, когда объект
однажды уже записанный в поток, спустя какое-то
время записывается в него снова. По умолчанию,
ObjectOutputStream сохраняет ссылки на объекты,
которые в него записываются. Это означает, что
если состояние записываемого объекта,
который уже был записан, будет записано снова,
новое состояние не сохраняется!

48
Сериализация в Java
Кэширование объектов в потоке
ObjectOutputStream out = new ObjectOutputStream(...);
MyObject obj = new MyObject(); // должен быть Serializable
obj.setState(100);
out.writeObject(obj); // сохраняет объект с состоянием = 100
obj.setState(200);
out.writeObject(obj); // не сохраняет новое состояние объекта

49
Сериализация в Java
Кэширование объектов в потоке
Решение:
1) Можно каждый раз после вызова метода записи
убеждаться в том, что поток закрыт;
2) Можно вызвать метод
objectOutputStream.reset(), который
сигнализирует потоку о том, что необходимо
освободить кэш от ссылок, которые он хранит,
чтобы новые вызовы методов записи
действительно записывали данные. Будьте
осторожны, reset очищает весь кэш объекта,
поэтому все ранее записанные объекты могут
быть перезаписаны заново.
50
Сериализация в Java
Производительность
Сериализация « по умолчанию» является
«медленной» операцией. Она в среднем в 2 – 2,5
раза медленнее записи в поток стандартными
средствами ввода-вывода.
Кроме того, так как ссылки на объекты кэшируются
в поток вывода, система не может выполнять сбор
мусора для записанных в поток объектов если
поток не был закрыт. Лучшее решение (как всегда
при помощи операций ввода/вывода) - это как
можно скорее закрывать потоки после выполнения
записи.

51

Contenu connexe

Tendances

Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.Roman Brovko
 
Лекция 6. Классы 1.
Лекция 6. Классы 1.Лекция 6. Классы 1.
Лекция 6. Классы 1.Roman Brovko
 
Лекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GILЛекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GILRoman Brovko
 
Лекция 1. Начало.
Лекция 1. Начало.Лекция 1. Начало.
Лекция 1. Начало.Roman Brovko
 
Java. Сборщик мусора. Работа с памятью.
Java.  Сборщик мусора. Работа с памятью. Java.  Сборщик мусора. Работа с памятью.
Java. Сборщик мусора. Работа с памятью. Unguryan Vitaliy
 
Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Stfalcon Meetups
 
Clojure: Lisp for the modern world (русская версия)
Clojure: Lisp for the modern world (русская версия)Clojure: Lisp for the modern world (русская версия)
Clojure: Lisp for the modern world (русская версия)Alex Ott
 
контейнеры STL
контейнеры STLконтейнеры STL
контейнеры STLmcroitor
 
стандартная библиотека с++: введение
стандартная библиотека с++: введениестандартная библиотека с++: введение
стандартная библиотека с++: введениеmcroitor
 
Лекция 11. Тестирование.
Лекция 11. Тестирование.Лекция 11. Тестирование.
Лекция 11. Тестирование.Roman Brovko
 
Cpp/cli particularities
Cpp/cli particularitiesCpp/cli particularities
Cpp/cli particularitiesmcroitor
 
Лекция 9. Модули, пакеты и система импорта.
Лекция 9. Модули, пакеты и система импорта.Лекция 9. Модули, пакеты и система импорта.
Лекция 9. Модули, пакеты и система импорта.Roman Brovko
 
Лекция 3. Декораторы и модуль functools.
Лекция 3. Декораторы и модуль functools.Лекция 3. Декораторы и модуль functools.
Лекция 3. Декораторы и модуль functools.Roman Brovko
 

Tendances (15)

Discovering Lambdas (Speech)
Discovering Lambdas (Speech)Discovering Lambdas (Speech)
Discovering Lambdas (Speech)
 
Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.
 
Лекция 6. Классы 1.
Лекция 6. Классы 1.Лекция 6. Классы 1.
Лекция 6. Классы 1.
 
Лекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GILЛекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GIL
 
Лекция 1. Начало.
Лекция 1. Начало.Лекция 1. Начало.
Лекция 1. Начало.
 
Java. Сборщик мусора. Работа с памятью.
Java.  Сборщик мусора. Работа с памятью. Java.  Сборщик мусора. Работа с памятью.
Java. Сборщик мусора. Работа с памятью.
 
Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Discovering Lambdas in Java 8
Discovering Lambdas in Java 8
 
Clojure: Lisp for the modern world (русская версия)
Clojure: Lisp for the modern world (русская версия)Clojure: Lisp for the modern world (русская версия)
Clojure: Lisp for the modern world (русская версия)
 
контейнеры STL
контейнеры STLконтейнеры STL
контейнеры STL
 
стандартная библиотека с++: введение
стандартная библиотека с++: введениестандартная библиотека с++: введение
стандартная библиотека с++: введение
 
Лекция 11. Тестирование.
Лекция 11. Тестирование.Лекция 11. Тестирование.
Лекция 11. Тестирование.
 
Cpp/cli particularities
Cpp/cli particularitiesCpp/cli particularities
Cpp/cli particularities
 
Лекция 9. Модули, пакеты и система импорта.
Лекция 9. Модули, пакеты и система импорта.Лекция 9. Модули, пакеты и система импорта.
Лекция 9. Модули, пакеты и система импорта.
 
Лекция 3. Декораторы и модуль functools.
Лекция 3. Декораторы и модуль functools.Лекция 3. Декораторы и модуль functools.
Лекция 3. Декораторы и модуль functools.
 
Java. Методы
Java. Методы Java. Методы
Java. Методы
 

En vedette

Стажировка-2013, разработчики, занятие 6. Внешние конфиги, сборка, автотесты
Стажировка-2013, разработчики, занятие 6. Внешние конфиги, сборка, автотестыСтажировка-2013, разработчики, занятие 6. Внешние конфиги, сборка, автотесты
Стажировка-2013, разработчики, занятие 6. Внешние конфиги, сборка, автотесты7bits
 
Лекция 6
Лекция 6Лекция 6
Лекция 6itc73
 
Jaxp Xmltutorial 11 200108
Jaxp Xmltutorial 11 200108Jaxp Xmltutorial 11 200108
Jaxp Xmltutorial 11 200108nit Allahabad
 
2 dtd - validating xml documents
2   dtd - validating xml documents2   dtd - validating xml documents
2 dtd - validating xml documentsgauravashq
 

En vedette (7)

Стажировка-2013, разработчики, занятие 6. Внешние конфиги, сборка, автотесты
Стажировка-2013, разработчики, занятие 6. Внешние конфиги, сборка, автотестыСтажировка-2013, разработчики, занятие 6. Внешние конфиги, сборка, автотесты
Стажировка-2013, разработчики, занятие 6. Внешние конфиги, сборка, автотесты
 
Лекция 6
Лекция 6Лекция 6
Лекция 6
 
Jaxp Xmltutorial 11 200108
Jaxp Xmltutorial 11 200108Jaxp Xmltutorial 11 200108
Jaxp Xmltutorial 11 200108
 
Mockito tutorial for beginners
Mockito tutorial for beginnersMockito tutorial for beginners
Mockito tutorial for beginners
 
2 dtd - validating xml documents
2   dtd - validating xml documents2   dtd - validating xml documents
2 dtd - validating xml documents
 
Spring in java
Spring in javaSpring in java
Spring in java
 
Mockito
MockitoMockito
Mockito
 

Similaire à 5. java lecture io

работа с потоками ввода вывода
работа с потоками ввода выводаработа с потоками ввода вывода
работа с потоками ввода выводаmetaform
 
Лекция 5
Лекция 5Лекция 5
Лекция 5itc73
 
Msu.Center.Lectures.J06 Io
Msu.Center.Lectures.J06 IoMsu.Center.Lectures.J06 Io
Msu.Center.Lectures.J06 Ioolegol
 
06 Ввод-вывод
06 Ввод-вывод06 Ввод-вывод
06 Ввод-выводphearnot
 
C# Desktop. Занятие 04.
C# Desktop. Занятие 04.C# Desktop. Занятие 04.
C# Desktop. Занятие 04.Igor Shkulipa
 
Java. Работа с файловой системой. Потоки ввода-вывода.
Java. Работа с файловой системой. Потоки ввода-вывода.Java. Работа с файловой системой. Потоки ввода-вывода.
Java. Работа с файловой системой. Потоки ввода-вывода.Unguryan Vitaliy
 
Java осень 2013 лекция 6
Java осень 2013 лекция 6Java осень 2013 лекция 6
Java осень 2013 лекция 6Technopark
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя:опыт статического анализа исходного кода200 open source проектов спустя:опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кодаPositive Hack Days
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кодаAndrey Karpov
 
Java осень 2014 занятие 6
Java осень 2014 занятие 6Java осень 2014 занятие 6
Java осень 2014 занятие 6Technopark
 
Инструментация среды исполнения в арсенале тестировщика
Инструментация среды исполнения в арсенале тестировщикаИнструментация среды исполнения в арсенале тестировщика
Инструментация среды исполнения в арсенале тестировщикаSQALab
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...Alexey Paznikov
 
Иван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программированиеИван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программированиеYandex
 
Web осень 2013 лекция 2
Web осень 2013 лекция 2Web осень 2013 лекция 2
Web осень 2013 лекция 2Technopark
 

Similaire à 5. java lecture io (20)

Step 6
Step 6Step 6
Step 6
 
работа с потоками ввода вывода
работа с потоками ввода выводаработа с потоками ввода вывода
работа с потоками ввода вывода
 
Lec 5
Lec 5Lec 5
Lec 5
 
Лекция 5
Лекция 5Лекция 5
Лекция 5
 
file handling in c++
file handling in c++file handling in c++
file handling in c++
 
Msu.Center.Lectures.J06 Io
Msu.Center.Lectures.J06 IoMsu.Center.Lectures.J06 Io
Msu.Center.Lectures.J06 Io
 
06 Ввод-вывод
06 Ввод-вывод06 Ввод-вывод
06 Ввод-вывод
 
C# Desktop. Занятие 04.
C# Desktop. Занятие 04.C# Desktop. Занятие 04.
C# Desktop. Занятие 04.
 
Java. Работа с файловой системой. Потоки ввода-вывода.
Java. Работа с файловой системой. Потоки ввода-вывода.Java. Работа с файловой системой. Потоки ввода-вывода.
Java. Работа с файловой системой. Потоки ввода-вывода.
 
Java осень 2013 лекция 6
Java осень 2013 лекция 6Java осень 2013 лекция 6
Java осень 2013 лекция 6
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя:опыт статического анализа исходного кода200 open source проектов спустя:опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода
 
Java осень 2014 занятие 6
Java осень 2014 занятие 6Java осень 2014 занятие 6
Java осень 2014 занятие 6
 
Инструментация среды исполнения в арсенале тестировщика
Инструментация среды исполнения в арсенале тестировщикаИнструментация среды исполнения в арсенале тестировщика
Инструментация среды исполнения в арсенале тестировщика
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
 
Step cpp0201
Step cpp0201Step cpp0201
Step cpp0201
 
JavaDay'14
JavaDay'14JavaDay'14
JavaDay'14
 
Programming c++ (begin-if-else)
Programming c++ (begin-if-else)Programming c++ (begin-if-else)
Programming c++ (begin-if-else)
 
Иван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программированиеИван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программирование
 
Web осень 2013 лекция 2
Web осень 2013 лекция 2Web осень 2013 лекция 2
Web осень 2013 лекция 2
 

Plus de MERA_school

2. java lecture syntax
2. java lecture syntax2. java lecture syntax
2. java lecture syntaxMERA_school
 
7. java lecture events
7. java lecture events7. java lecture events
7. java lecture eventsMERA_school
 
6. java lecture swing
6. java lecture swing6. java lecture swing
6. java lecture swingMERA_school
 
4. java lecture exceptions
4. java lecture exceptions4. java lecture exceptions
4. java lecture exceptionsMERA_school
 
3. java lecture classes
3. java lecture classes3. java lecture classes
3. java lecture classesMERA_school
 
1. java lecture intro
1. java lecture intro1. java lecture intro
1. java lecture introMERA_school
 

Plus de MERA_school (6)

2. java lecture syntax
2. java lecture syntax2. java lecture syntax
2. java lecture syntax
 
7. java lecture events
7. java lecture events7. java lecture events
7. java lecture events
 
6. java lecture swing
6. java lecture swing6. java lecture swing
6. java lecture swing
 
4. java lecture exceptions
4. java lecture exceptions4. java lecture exceptions
4. java lecture exceptions
 
3. java lecture classes
3. java lecture classes3. java lecture classes
3. java lecture classes
 
1. java lecture intro
1. java lecture intro1. java lecture intro
1. java lecture intro
 

5. java lecture io

  • 1. Консольный ввод-вывод Байтовые и символьные потоки Аналогично языку С++ ввод/вывод в языке Java выполняется с использованием потоков. Поток ввода/вывода - это некоторый условный канал, по которому отсылаются и получаются данные. В Java 2 реализованы 2 типа потоков: байтовые и символьные. Байтовые потоки предоставляют удобные средства для обработки, ввода и вывода байтов или других двоичных объектов. Символьные потоки используются для обработки, ввода и вывода символов или строк в кодировке Unicode. Все классы для консольного I/O – пакет java.io: import java.io.*; 1
  • 3. Консольный ввод-вывод Байтовые потоки. Абстрактный класс InputStream. public abstract int read() throws IOException Читает 1 байт из вх. потока. Результат в младшем байте. public int read (byte[ ] b) throws IOException Читает послед-ть байт в массив b[ ]. Возвращает колво прочитанных байт или -1. public int read (byte[ ] b, int off, int len) throws IOException Заполняет массив с указанного байта, читает не более len символов public long skip (long n) throws IOException Пропускает n байт в потоке int available () Возвращает кол-во доступных байт в потоке. void close () Закрывает поток ввода. 3
  • 4. Консольный ввод-вывод Байтовые потоки. Класс FileInputStream. FileInputStream(String name) throws FileNotFoundException FileInputStream (File file) throws FileNotFoundException В классе FileInputStream переопределяется большая часть методов класса Input-Stream (в т.ч. абстрактный метод read() ). Когда создается объект класса FileInputStream, он одновременно с этим открывается для чтения. 4
  • 5. Консольный ввод-вывод Байтовые потоки. Класс FileInputStream. import java.io.*; System.out.println("Still Available: " + fp.available()); System.out.println("Total Still Available: " + fp.available()); class FileInputTest System.out.println("Skipping another 1/4: skip()"); System.out.println("Reading the next 1/4: read(b[ ])"); {public static void main(String args[ ]) throws Exception fp.skip(size/4); byte b[ ] = new byte[size/4]; {int size; System.out.println("Still Available: " + fp.available()); if (fp.read(b) == -1) InputStream fp = new FileInputStream("FileInputTest.java"); System.out.println("Reading 1/8 into the end of array"); {System.out.println("End of File"); } sizeif=(f1.read(b, b.length-size/8, size/8) == -1) fp.available(); for (int i=0; i < size/4; i++) System.out.println("Total Available Bytes: " + size); {System.out.println("End of File”); } {System.out.print((char) b[i]); } System.out.println("First 1/4Available: "read()"); System.out.println("Still of the file: + f1.available()); for (int i=0; i < } fp.close(); size/4; i++) {System.out.print((char) fp.read()); } } 5
  • 6. Консольный ввод-вывод Байтовые потоки. Класс ByteArrayInputStream. ByteArrayInputStream – это реализация входного потока, в котором в качестве источника используется массив типа byte. У этого класса два конструктора, каждый из которых в качестве первого параметра требует байтовый массив. ByteArrayInputStream(byte array[ ]) ByteArrayInputStream(byte array[ ], int start, int numBytes) 6
  • 7. Консольный ввод-вывод Байтовые потоки. Класс ByteArrayInputStream. import java.io.*; class ByteArrayTest {public static void main(String args [ ]) throws IOException {byte b[ ] = {0,1,2,3,4,5,6,7,8,9}; ByteArrayInputStream input1 = new ByteArrayInputStream(b); ByteArrayInputStream input2 = new ByteArrayInputStream(b,0,3); } } 7
  • 8. Консольный ввод-вывод Байтовые потоки. Абстрактный класс OutputStream. public abstract void write (int b) throws IOException Записывает 1 байт в выходной поток. public void write (byte[ ] b) throws IOException Записывает в поток массив байт public void write (byte[ ] b, int off, int len) throws IOException Записывает часть массива в поток (len элементов начиная с элемента off) public void flush() throws IOException Немедленно выталкивает из буфера в поток все что накоплено в буфере. public void close() throws IOException Закрывает поток. 8
  • 9. Консольный ввод-вывод Байтовые потоки. Класс FileOutputStream. Класс FileOutputStream можно применять для записи байтов в файл. У класса FileOutputStream есть 3 конструктора: FileOutputStream (String filePath) throws FileNotFoundException FileOutputStream (File fileObj) throws FileNotFoundException FileOutputStream (String filePath, boolean append) throws FileNotFoundException - filePath – полное имя файла, - fileObj – объект типа File, который описывает файл - append (=true – добавление информации в существующий файл) 9
  • 10. Консольный ввод-вывод Байтовые потоки. Класс FileOutputStream. try {FileInputStream Source = new FileInputStream("infile.dat"); FileOutputStream Dest = new FileOutputStream("outfile.dat"); int c; while ((c = Source.read()) != -1) {Dest.write(c); } } catch (FileNotFoundException ex) {… } finally {Source.close(); Dest.close(); } 10
  • 11. Консольный ввод-вывод Байтовые потоки. Класс ByteArrayOutputStream. ByteArrayOutputStream( ); - 32 байта ByteArrayOutputStream(int numBytes); Метод, записывающий содержимое одного потока в другой: public void writeTo(OutputStream out) throws IOException byte buf [ ] = {‘a’,’b’,’c’,’d’}; ByteArrayOutputStream b = new ByteArrayOutputStream(); b.write(buf); FileOutputStream f = new FileOutputStream(“result.txt”); b.writeTo(f); 11
  • 12. Консольный ввод-вывод Символьные потоки. В Java символы хранятся в кодировке Unicode. Символьный поток I/O автоматически транслирует Символы между форматом Unicode и локальной кодировкой, пользовательского ПК. 12
  • 14. Консольный ввод-вывод Символьные потоки. Методы классов Reader и Writer аналогичны методам классов InputStream и OutputStream с той разницей, что все аргументы типа byte заменены на аргументы типа char. Классы CharArrayReader и CharArrayWriter соответствуют классам ByteArrayInputStream и ByteArrayOutputStream с той же разницей. Классы FileReader и FileWriter являются символьными версиями потоковых классов FileInputStream и FileOutputStream. 14
  • 15. Консольный ввод-вывод Символьные потоки. Классы InputStreamReader и OutputStreamWriter – переходники между байтовыми и символьными потоками. Байтовый поток используется для физического ввода-вывода, а символьный поток преобразует байты в символы с учетом кодировки. InputStreamReader (InputStream obj) OutputStreamWriter (OutputStream out) 15
  • 16. Консольный ввод-вывод Буферизованный ввод-вывод. В библиотеке Java имеются также буферизованные потоки I/O. Для буферизованных потоков операции чтения и записи происходят с буфером, находящимся в памяти. Когда буфер пуст выполняется реальная операция чтения из потока, когда буфер полон – реальная операция записи в поток. Буферизация может быть добавлена к любому байтовому либо символьному потоку с помощью специальных классов «оболочек» (“wrappers”). При этом конструктору буферизованного потока передается не буферизованный поток. 16
  • 17. Консольный ввод-вывод Буферизованный ввод-вывод. Буферизованные потоки I/O: BufferedInputStream, BufferedOutputStream байтовые BufferedReader, BufferedWriter – символьные Конструкторы: BufferedInputStream(InputStream in) BufferedOutputStream(OutputStream out) BufferedReader(Reader in) BufferedWriter(Writer out) 17
  • 18. Консольный ввод-вывод Пример организации консольного ввода-вывода В пакете java.lang есть класс с именем System. В классе System определены три переменные: public static InputStream in; public static PrintStream out; public static PrintStream err; System.out и System.err – байтовые потоки, эмулирующие поддержку локального character set ! System.in – байтовый поток ! 18
  • 19. Консольный ввод-вывод Пример организации консольного ввода int a; String str; BufferedReader br = = new BufferedReader( new InputStreamReader( System.in ) ); Буферизованный Символьный поток Байтовый поток поток ввода ввода ввода str = br.readLine(); a = Integer.parseInt(str); 19
  • 20. Консольный ввод-вывод Пример организации консольного вывода Класс PrintStream содержит методы print() и println() для всех базовых типов данных. Т.о. для консольного вывода надо вызвать System.out.print() или System.out.println() System.out.println (“Значение а = ” +а); System.out.print (str); 20
  • 21. Консольный ввод-вывод Класс Scanner начиная с JSDK 1.5 import java.util.Scanner; … Scanner sc = new Scanner(System.in); … System.out.println(“Input a:”); int a = sc.nextInt(); System.out.println(“Input str:”); String str = sc.next(); Подробнее см. http://docs.oracle.com/javase/1.5.0/docs/api/index.html?java/util/Scanner.html 21
  • 22. Консольный ввод-вывод Класс File Класс File представляет имя файла, но не сам файл (если файл не существует, он не создается, если существует с ним можно проводить производить операции через объект File) ! Конструкторы: public File(String pathname) public File(String pathname, String filename) public File (File parent, String child) 22
  • 23. Консольный ввод-вывод Класс File public boolean exists() Существует ли файл? public boolean canRead() Возможен ли доступ на чтение? public boolean canWrite() Возможен ли доступ на запись public boolean isHidden() Является ли файл скрытым? public boolean isFile() Файл? public boolean isDirectory() Каталог? public boolean delete() Удаляет файл, если он существует. Каталог удаляется только если он пуст. public String[ ] list() Возвращает список файлов в каталоге 23
  • 24. Консольный ввод-вывод Класс File public boolean mkdir() Создает пустой каталог public boolean renameTo (File newName) Переименование файла public boolean setReadOnly() Устанавливает атрибут ReadOnly 24
  • 25. Сериализация в Java Что такое сериализация? Сериализация это процесс сохранения состояния объекта в последовательность байт; десериализация это процесс восстановления объекта из этих байт. Java Serialization API предоставляет стандартный механизм для создания сериализуемых объектов. 25
  • 26. Сериализация в Java Для чего нужна сериализация? В Java всё представлено в виде объектов. Если двум компонентам Java необходимо общаться друг с другом, то им необходим механизм для обмена данными. Следовательно, должен быть универсальный и эффективный протокол передачи объектов между компонентами. Сериализация создана для этого, и компоненты Java используют этот протокол для передачи объектов. 26
  • 27. Сериализация в Java 3 механизма сериализации Сериализация 1) используя протокол по умолчанию 2) модифицируя протокол по умолчанию 3) создавая свой собственный протокол 27
  • 28. Сериализация в Java 1) Протокол по умолчанию Чтобы объект стал сериализуемым, необходимо, чтобы он реализовывал интерфейс java.io.Serializable. Интерфейс Serializable это интерфейсмаркер; в нём не задекларировано ни одного метода. Но он говорит сериализующему механизму, что класс может быть сериализован. 28
  • 29. Сериализация в Java 1) Протокол по умолчанию. Сохранение объекта import java.io.Serializable; import java.util.Date; import java.util.Calendar; public class PersistentTime implements Serializable { private Date time; public PersistentTime() { time = Calendar.getInstance().getTime(); } public Date getTime() { return time; } } 29
  • 30. Сериализация в Java 1) Протокол по умолчанию. Сохранение объекта Для сохранения объекта как последовательности байт используется класс java.io.ObjectOutputStream Этот класс является фильтрующим потоком (filter stream) - он окружает низкоуровневый поток байтов (называемый узловым потоком (node stream)) и предоставляет нам поток сериализации. Узловые потоки могут быть использованы для записи в файловую систему, сокеты и т.д. Это означает, что можно, например, передавать разложенные на байты объекты по сети и затем восстанавливать их на других компьютерах!30
  • 31. Сериализация в Java 1) Протокол по умолчанию. Сохранение объекта import java.io.ObjectOutputStream; import java.io.FileOutputStream; import java.io.IOException; public class FlattenTime { public static void main(String [] args) { String filename = "time.ser"; PersistentTime time = new PersistentTime(); FileOutputStream fos = null; ObjectOutputStream out = null; 31
  • 32. Сериализация в Java 1) Протокол по умолчанию. Сохранение объекта try { fos = new FileOutputStream(filename); out = new ObjectOutputStream(fos); out.writeObject(time); //сериализация out.close(); } catch(IOException ex) { ex.printStackTrace(); } } } 32
  • 33. Сериализация в Java 1) Протокол по умолчанию. Восстановление объекта Для восстановления объекта используется метод readObject() класса java.io.ObjectInputStream. Метод считывает последовательность байтов и создает объект, полностью повторяющий оригинал. Поскольку readObject() может считывать любой сериализуемый объект, необходимо его присвоение соответствующему типу. Т.о., из системы, в которой происходит восстановление объекта, должен быть доступен файл класса. Т.е. при сериализации не сохраняется ни файл класса объекта, ни его методы, сохраняется лишь состояние объекта. 33
  • 34. Сериализация в Java 1) Протокол по умолчанию. Восстановление объекта import java.io.ObjectInputStream; import java.io.FileInputStream; import java.io.IOException; import java.util.Calendar; public class InflateTime { public static void main(String [] args) { String filename = "time.ser"; PersistentTime time = null; FileInputStream fis = null; ObjectInputStream in = null; 34
  • 35. Сериализация в Java 1) Протокол по умолчанию. Восстановление объекта try { fis = new FileInputStream(filename); in = new ObjectInputStream(fis); time = (PersistentTime)in.readObject(); //десериализация in.close(); } catch(IOException ex) { ex.printStackTrace(); } catch(ClassNotFoundException ex) { ex.printStackTrace(); } 35
  • 36. Сериализация в Java 1) Протокол по умолчанию. Восстановление объекта // распечатать восстановленное время System.out.println("Время сохранения: " + time.getTime()); System.out.println(); // распечатать текущее время System.out.println("Текущее время: " + Calendar.getInstance().getTime()); } } 36
  • 37. Сериализация в Java 1) Протокол по умолчанию. Ограничения сериализации 1) Если в состав сериализуемого класса A входит поле класса B, то класс B тоже должен быть сериализуемым. Иначе в процессе сериализации возникнет исключение NotSerializableException . 2) В процессе сериализации/ десериализации не участвуют статические поля класса, поскольку они фактически являются не полями объектов (экземпляров класса), а полями класса в целом. 3) Влияние наследования на сериализацию. Пусть класс A объявлен, как сериализуемый. От него унаследован класс B, для которого не указано implements Serializable . От B порожден класс C - сериализуемый. Тогда при сериализации будут сохранены все поля классов A и C , но не B . 37
  • 38. Сериализация в Java 1) Протокол по умолчанию. Несериализуемые поля Класс java.lang.Object не реализует Serializable, поэтому не все объекты Java могут быть автоматически сохранены. Например, некоторые системные классы, такие как Thread, OutputStream и его подклассы, и Socket - не сериализуемые. Причина: сериализация таких классов бессмысленна. 38
  • 39. Сериализация в Java 1) Протокол по умолчанию. Несериализуемые поля Проблема: есть класс, который содержит экземпляр Thread? Можем ли мы в этом случае сохранить объект такого типа? Решение: мы имеем возможность сообщить механизму сериализации о своих намерениях, пометив объект Thread нашего класса как несохраняемый - transient. 39
  • 40. Сериализация в Java 1) Протокол по умолчанию. Несериализуемые поля import java.io.Serializable; public class PersistentAnimation implements Serializable, Runnable { transient private Thread animator; private int animationSpeed; public PersistentAnimation(int animationSpeed) { this.animationSpeed = animationSpeed; animator = new Thread(this); animator.start(); } public void run() { … } } 40
  • 41. Сериализация в Java 2) Модификация протокола по умолчанию. Проблема: как перезапустить анимацию? Когда мы создаем объект при помощи new, конструктор объекта вызывается только при создании нового экземпляра. Читая объект методом readObject() мы не создаем нового экземпляра, мы просто восстанавливаем сохраненный объект. В результате анимационный поток запустится лишь однажды, при первом создании экземпляра этого объекта. 41
  • 42. Сериализация в Java 2) Модификация протокола по умолчанию. Решение: private void writeObject(ObjectOutputStream out) throws IOException; private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException; Виртуальная машина при вызове соответствующего метода автоматически проверяет, не были ли они объявлены в классе объекта. 42
  • 43. Сериализация в Java 2) Модификация протокола по умолчанию. import java.io.Serializable; public class PersistentAnimation implements Serializable, Runnable { transient private Thread animator; private int animationSpeed; public PersistentAnimation(int animationSpeed) { this.animationSpeed = animationSpeed; startAnimation(); } public void run() { … } 43
  • 44. Сериализация в Java 2) Модификация протокола по умолчанию. private void startAnimation() { animator = new Thread(this); animator.start(); } private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); //мы не меняем нормальный процесс } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); //мы лишь дополняем его startAnimation(); } 44
  • 45. Сериализация в Java 2) Модификация протокола по умолчанию. Запрет сериализации для класса. Проблема: class A implements Serializable { … } class B extends A { … } Как запретить сериализацию для класса В? 45
  • 46. Сериализация в Java 2) Модификация протокола по умолчанию. Запрет сериализации для класса. Решение: private void writeObject(ObjectOutputStream out) throws IOException { throw new NotSerializableException(“Non serializable class!"); } private void readObject(ObjectInputStream in) throws IOException { throw new NotSerializableException (“Non serializable class!"); } 46
  • 47. Сериализация в Java 3) Создание собственного протокола Вместо реализации интерфейса Serializable, можно реализовать интерфейс Externalizable, который содержит два метода: public void writeExternal(ObjectOutput out) throws IOException; public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException; Для создания собственного протокола надо переопределить эти методы. Здесь ничего не делается автоматически. Это наиболее сложный, но и наиболее контролируемый способ. 47
  • 48. Сериализация в Java Кэширование объектов в потоке Проблема: Рассмотрим ситуацию, когда объект однажды уже записанный в поток, спустя какое-то время записывается в него снова. По умолчанию, ObjectOutputStream сохраняет ссылки на объекты, которые в него записываются. Это означает, что если состояние записываемого объекта, который уже был записан, будет записано снова, новое состояние не сохраняется! 48
  • 49. Сериализация в Java Кэширование объектов в потоке ObjectOutputStream out = new ObjectOutputStream(...); MyObject obj = new MyObject(); // должен быть Serializable obj.setState(100); out.writeObject(obj); // сохраняет объект с состоянием = 100 obj.setState(200); out.writeObject(obj); // не сохраняет новое состояние объекта 49
  • 50. Сериализация в Java Кэширование объектов в потоке Решение: 1) Можно каждый раз после вызова метода записи убеждаться в том, что поток закрыт; 2) Можно вызвать метод objectOutputStream.reset(), который сигнализирует потоку о том, что необходимо освободить кэш от ссылок, которые он хранит, чтобы новые вызовы методов записи действительно записывали данные. Будьте осторожны, reset очищает весь кэш объекта, поэтому все ранее записанные объекты могут быть перезаписаны заново. 50
  • 51. Сериализация в Java Производительность Сериализация « по умолчанию» является «медленной» операцией. Она в среднем в 2 – 2,5 раза медленнее записи в поток стандартными средствами ввода-вывода. Кроме того, так как ссылки на объекты кэшируются в поток вывода, система не может выполнять сбор мусора для записанных в поток объектов если поток не был закрыт. Лучшее решение (как всегда при помощи операций ввода/вывода) - это как можно скорее закрывать потоки после выполнения записи. 51