Transcript
Page 1: Java осень 2012 лекция 6

Углубленное программирование на Java

Лекция 6. «I/O»

Виталий Чибриков

Page 2: Java осень 2012 лекция 6

Схема сервера

utils: timeService, rndService, vfs base

messageSystem

frontend dbService

main

gameMechanics

resourceSystem

Page 3: Java осень 2012 лекция 6

План лекции

Events

I/O streams

Callbacks

Random

Singleton и Context

Анонимные классы

Time & Date

VFS

Page 4: Java осень 2012 лекция 6

Random

Как получить случайное число?

Как получить псевдослучайное число?

Random rnd = new Random();rnd.nextInt(100); – вернет случайное число от 0 до 100При каждом запуске последовательность будет новой

Random rnd = new Random(1L);rnd.nextInt(100); – вернет случайное число от 0 до 100При каждом запуске последовательность будет прежней

Math.random(); – вернет случайное число типа double от 0 до 1При каждом запуске последовательность будет новой

Page 5: Java осень 2012 лекция 6

Singleton и Context

Шаблон проектирования Singleton

Позволяет создать только один объект данного типа на процесс

Аналог статического поля, но позволяет позднюю инициализацию

Singleton

Содержит статическое поле типа своего же класса (instance)

Приватный конструктор

Статический метод instance() который возвращает instance класса

Page 6: Java осень 2012 лекция 6

Singleton и Context

Context – контейнер class -> объект класа

Позволяет создать только те объекты, которые нужны процессу

public class Context {private Map<Class<?>, Object> context = new HashMap<Class<?>, Object>();

public void add(Class<?> clazz, Object object){if(!object.getClass().equals(clazz)){

//ERROR}if(context.containsKey(clazz)){

//ERROR}context.put(clazz, object);

}

public Object get(Class<?> clazz){return context.get(clazz);

}}

Page 7: Java осень 2012 лекция 6

План лекции

Events

I/O streams

Callbacks

Random

Singleton и Context

Анонимные классы

Time & Date

VFS

Page 8: Java осень 2012 лекция 6

Events

Задача:

Служба в которой происходят некоторые события – EventSource

Службы которые должны реагировать на эти события – EventListeners

Нужен механизм оповещения о событии и передачи инфораци об источнике

Реализация:

EventSource

EventListenerInterface

EventListenerImpl

java.util.EventObject

Page 9: Java осень 2012 лекция 6

Event listener

public interface MyEventListener { public void handle(EventObject event);}

public class MyEventListenerImpl implements MyEventListener {

//code

public void handle(EventObject event){ //process event}

}

Page 10: Java осень 2012 лекция 6

Event source

public class MyEventSource {private List<MyEventListener> listeners =

Collections.synchronizedList(new ArrayList<MyEventListener>()); public void addListener(MyEventListener listener){

listeners.add(listener);} public void removeListener(MyEventListener listener){

listeners.remove(listener); }

public void fireEvent(){EventObject event = new EventObject(this);for(MyEventListener listner : listeners){

listner.handle(event);}

}}

Page 11: Java осень 2012 лекция 6

Callbacks

Задача:

Вы используете внешнюю библиотеку

Событие во внешней библиотеке должно повлиять на ваш код

Ваш метод который будет вызван по событию – callback

Реализация:Вы должны передать в библиотеку свой метод

В С++: ссылка на функцию

В С#: делегаты

В Java: вы передаете объект реализующий библиотечный интерфейс

Пример:

class HelloWorld extends AbstractHandler – из примера jetty

public void handle(...) это callback

Page 12: Java осень 2012 лекция 6

Анонимные классы

Если вы передаете в метод новый объект класса по интерфейсу,НЕ обязятельно создавать отдельный класс.

Явное создание класса

interface A{getA();

}

class AImpl{getA(){…}

}

class B{static void proccessA(A a){…}

static void main(String[] args){B.proccessA(new AImpl());

}}

interface A{getA();

}

class B{static void proccessA(A a){…}

static void main(String[] args){B.proccessA(new A (){

getA(){…}

});}

}

Анонимный класс

Точно также можно создать анонимный наследник абстактного класса

Page 13: Java осень 2012 лекция 6

План лекции

Events

I/O streams

Callbacks

Random

Singleton и Context

Анонимные классы

Time & Date

VFS

Page 14: Java осень 2012 лекция 6

Time & Date

Работа со временем

От миллисекунд до даты

UNIX или POSIX time – время с 1 января 1970 в секундах

Фарматирование даты и времени для пользователей

Работу со временем лучше перенести в TimeHelper

Как хранить время в приложении и в базе

Подписка на таймер

Page 15: Java осень 2012 лекция 6

TimeHelper

public class TimeHelper {public static long getTimeInMs(){

Date date = new Date();return date.getTime();//return System.currentTimeMillis();

}

public static int getPOSIX(){Date date = new Date();int millisInSecond = 1000;return (int)(date.getTime() / millisInSecond);

}

public static String getUserDateFull(Locale locale){Date date = new Date();DateFormat dateFormatter =

DateFormat. getDateInstance(DateFormat.FULL, locale);return dateFormatter.format(date);

}}

Page 16: Java осень 2012 лекция 6

Timer

java.unil.Timer

java.unil.TimerTask

Порядок работы:

Создаем timer

Создаем класс унаследованный от TimerTask

Пишем в методе run() код который будет выполнен по таймеру

Передаем в timer таск и время через кторое надо выполнить таск

PROFIT!!!

Выключаем timer через timer.cancel();

Ждем положенное время

Page 17: Java осень 2012 лекция 6

Timer

int timeMs = 10000;TimeService.instance().start();TimeService.instance().sheduleTask(new TimerTask(){

public void run() {System.out.append("Timer run!\n");TimeService.instance().stop();

}

}, timeMs);

Page 18: Java осень 2012 лекция 6

План лекции

Events

I/O streams

Callbacks

Random

Singleton и Context

Анонимные классы

Time & Date

VFS

Page 19: Java осень 2012 лекция 6

I/O, потоки

I/O – общение с внешними устройствами (файлы, принтеры, сеть и т.д.)

Поток – объект который передставляет источник или приемник данных

Поток основан на последовательности битов данных

InputStream

OutputStream

Page 20: Java осень 2012 лекция 6

InputStream

public abstract class InputStream

Основные методы:

abstract int read()

int read(byte[] b)

void mark(int readlimit)

void reset()

void close()

Основная задача – читать байт за байтом из входного потока

Page 21: Java осень 2012 лекция 6

Byte Streams

OutputStream

InputStream

PrintStream

FilterOutputStream BufferedOutputStream

DataOutputStream

FileInputStream

FilterInputStream

FileOutputStream

BufferedInputStream

DataInputStream

Page 22: Java осень 2012 лекция 6

FilterInputStream

public class FilterInputStream extends InputStream

Переопредляет все методы InputStream вызывая методы поля in

private InputStream in;

protected FilterInputStream(InputStream in){this.in = in;

}

Наследники этого класса могут менять работу потока в поле in

Page 23: Java осень 2012 лекция 6

FilterInputStream

Page 24: Java осень 2012 лекция 6

Character Streams

Writer

Reader

BufferedWriter

OutputStreamWriter

PrintWriter

FileWriter

FileReader

BufferedReader

InputStreamReader

Page 25: Java осень 2012 лекция 6

SimpleFileReader

public class SimpleFileReader {public static void main(String args[]) throws IOException {

FileReader fr = new FileReader("SimpleFileReader.java"); BufferedReader br = new BufferedReader(fr); String currentLine; while((currentLine = br.readLine()) != null) {

System.out.println(currentLine);} fr.close();

} }

Page 26: Java осень 2012 лекция 6

CustomFileReader

public class CustomFileReader {public static void main(String args[]) throws IOException {

FileInputStream fstream = new FileInputStream("textfile.txt");DataInputStream in = new DataInputStream(fstream); InputStreamReader isr = new InputStreamReader(in, "UTF-16");BufferedReader br = new BufferedReader(isr);

String strLine;

while ((strLine = br.readLine()) != null) {System.out.println (strLine);

} br.close();

}}

Page 27: Java осень 2012 лекция 6

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

Для особождения ресурсов все потоки должны быть закрыты

BufferedReader br = null;try{

//codebr = new BufferedReader(isr); //code

} catch (Exception e){System.err.println("Error: " + e.getMessage());

} finally{if(br != null){

try {br.close();

} catch (IOException e) {System.err.println("Error: " + e.getMessage());

}}

}

Page 28: Java осень 2012 лекция 6

File

File – представление пути к файлу или директории

Скрыает от приложения детали пути к файлу конкретной ОС

Основные методы:

boolean exists();

String getAbsolutePath();

boolean isDirectory();

boolean createNewFile();

boolean mkdir();

boolean delete();

boolean deleteOnExit();

Page 29: Java осень 2012 лекция 6

План лекции

Events

I/O streams

Callbacks

Random

Singleton и Context

Анонимные классы

Time & Date

VFS

Page 30: Java осень 2012 лекция 6

VFS

Virtual File System – модуль для работы с файлами

public interface VFS {boolean isExist(String path);

boolean isDirectory(String path);

String getAbsolutePath(String file);

byte[] getBytes(String file);

String getUFT8Text(String file);

Iterator<String> getIterator(String startDir);}

public class VFSImpl implements VFS {

private String root;

public VFSImpl(String root){this.root = root;

}

Page 31: Java осень 2012 лекция 6

Iterator<String>

private class FileIterator implements Iterator<String>{

private Queue<File> files = new LinkedList<File>();

public FileIterator(String path){files.add(new File(root + path));

}public boolean hasNext() {

return !files.isEmpty();}public String next() {

File file = files.peek();if(file.isDirectory()){

for(File subFile : file.listFiles()){files.add(subFile);

}}return files.poll().getAbsolutePath();

}public void remove() {}

}

Page 32: Java осень 2012 лекция 6

Спасибо за вниманиеВиталий Чибриков

[email protected]