}

public static void main(String[] args) {

if(args. length < 1) usage();

if(args[0].equals("-r")) {

if(args. length!= 3) usage();

File

old = new File(args[1]),

rname = new File(args[2]);

old. renameTo(rname);

fileData(old);

fileData(rname);

return; // Выход из main

}

int count = 0;

boolean del = false;

if(args[0].equals("-d")) {

count++;

del = true;

}

for( ; count < args. length; count++) {

File f = new File(args[count]);

if(f. exists()) {

System. out. println(f + " exists");

if(del) {

System. out. println("deleting..." + f);

f. delete();

}

}

else { // Не существует

if(!del) {

f. mkdirs();

System. out. println("created " + f);

}

}

fileData(f);

}

}

}

В fileData( ) вы можете видеть различные способы исследования файла для отображения информации о файле или о пути директории.

Первый метод, который вызывается main( ) - это renameTo( ), который позволяет вам переименовать (или переместить) файл по введенному новому путь, представленному аргументом, который является другим объектом типа File. Это так же работает с директориями любой длины.

Если вы поэкспериментируете с приведенной выше программой, вы обнаружите, что вы можете создать путь директорий любой сложности, потому что mkdirs( ) будет делать всю работу за вас.

8.2 Ввод и вывод

Библиотеки ввода/вывода часто используют абстракцию потока, который представляется любым источником данных или представляется как объект, способный производить или принимать кусочки данных. Поток прячет детали того, что случается с данными внутри реального устройства ввода/вывода.

НЕ нашли? Не то? Что вы ищете?

Библиотечные классы Java для ввода/вывода делятся на классы ввода и вывода, как вы можете увидеть, взглянув на иерархию Java классов в онлайн документации с помощью вашего Web броузера. При наследовании, все, что наследуется от классов InputStream или Reader, имеет основной метод, называемый read( ) для чтения единичного байта или массива байт. Точно так же, все, что наследуется от классов OutputStream или Writer, имеет основной метод, называемый write( ) для записи единичного байта или массива байт. Однако чаще всего вы не можете использовать эти методы; они существуют для того, чтобы другие классы могли использовать их — эти другие классы обеспечивают более полезные интерфейсы. Таким образом, вы редко будете создавать ваш объект потока, используя единственный класс, вместо этого вы будите располагать множеством объектом для обеспечения желаемой функциональности. Факт в том что вы создаете более, чем один объект для создания единственного результирующего потока, это главная причина, по которой потоки Java являются запутанными.

Полезно распределить классы по категориям, исходя из их функциональности. В Java 1.0 разработчики библиотеки начали с решения, что все классы, которые могут что-то делать с вводом, должны наследоваться от InputStream, а все классы, которые ассоциируются с выводом, должны наследоваться от OutputStream.

Типы InputStream

Работа InputStream состоит в представлении классов, которые производят ввод от различных источников. Источниками могут быть:

1.  Массив байт.

2.  Объект String.

3.  Файл.

“Труба”, которая работает так же, как и физическая труба: вы помещаете вещи в один конец, а они выходят из другого.

Последовательность других потоков, так что вы можете собрать их вместе в единый поток.

Другие источники, такие как Internet соединение. (Это будет обсуждено в одной из следующих глав.)

Каждый из них имеет ассоциированный подкласс InputStream. Кроме того, FilterInputStream также имеет тип InputStream, для обеспечения базового класса для "декоративных" классов, которые присоединяют атрибуты или полезные интерфейсы для входного потока. Это будет обсуждаться дальше.

Таблица 11-1. Типы InputStream

Класс

Функция

Аргументы конструктора

Как его использовать

ByteArray-InputStream

Позволяет использовать буфер в памяти в качестве InputStream

Буфер, их которого извлекаются байты.

Как источник данных. Соединить его с объектом FilterInputStream для обеспечения полезного интерфейса.

StringBuffer-InputStream

Конвертирует String в InputStream

String. Лежащая в основе реализация на самом деле использует StringBuffer.

Как источник данных. Соединить его с объектом FilterInputStream для обеспечения полезного интерфейса.

File-InputStream

Для чтения информации из файла.

String, представляющий имя файла, или объекты File или FileDescriptor.

Как источник данных. Соединить его с объектом FilterInputStream для обеспечения полезного интерфейса.

Piped-InputStream

Производит данные, которые были записаны в ассоциированный PipedOutput-Stream. Реализует концепцию “трубопровода”.

PipedOutputStream

Как источник данных при нескольких нитях процессов. Соединить его с объектом FilterInputStream для обеспечения полезного интерфейса.

Sequence-InputStream

Преобразует два или более объектов InputStream в единый InputStream.

Два объекта InputStream или Enumeration для контейнера из InputStream.

Как источник данных. Соединить его с объектом FilterInputStream для обеспечения полезного интерфейса.

Filter-InputStream

Абстрактный класс, который является интерфейсом для декоратора, который обеспечивает полезную функциональность для других классов InputStream.

 

Типы OutputStream

Эта категория включает классы, которые решают, куда будет производиться вывод: в массив байт (но не String; возможно, вы можете создать его, используя массив байт), в файл, или в “трубу”.

Кроме того, FilterOutputStream обеспечивает базовый класс для "декорирования" классов, которые присоединяют атрибуты или полезные интерфейсы для выходного потока. Это будет обсуждаться позже.

Таблица 11-2. Типы OutputStream

Класс

Функция

Аргументы конструктора

Как его использовать

ByteArray-OutputStream

Создает буфер в памяти. Все данные, которые вы будете посылать в поток, помещаются в этот буфер.

необязательный начальный размер буфера.

Для определения места назначения ваших данных. Соедините его с объектом FilterOutputStream для обеспечения полезного интерфейса.

File-OutputStream

Для отсылки информации в файл.

Строка, представляющая имя файла, или объекты File или FileDescriptor.

Для определения места назначения ваших данных. Соедините его с объектом FilterOutputStream для обеспечения полезного интерфейса.

Piped-OutputStream

Любая информация, записанная сюда, автоматически становится вводом ассоциированного PipedInput-Stream. Реализует концепцию “трубопровода”.

PipedInputStream

Для определения назначения ваших данных со многими нитями процессов. Соедините его с объектом FilterOutputStream для обеспечения полезного интерфейса.

Filter-OutputStream

Абстрактный класс, который является интерфейсом для декоратора, который обеспечивает полезную функциональность другим классам OutputStream.

 

9. Потоки выполнения

9.1 Класс Thread

Основное понятие современных операционных систем — процесс (process). Как и все общие понятия, процесс трудно определить, да это и не входит в задачу. Можно понимать под процессом выполняющуюся (runnable) программу, но надо помнить о том, что у процесса есть несколько состояний. Процесс может в любой момент перейти к выполнению машинного кода другой программы, а также "заснуть" (sleep) на некоторое время, приостановив выполнение программы. Он может быть выгружен на диск. Количество состояний процесса и их особенности зависят от операционной системы.

Все современные операционные системы многозадачные (multitasking), они запускают и выполняют сразу несколько процессов. Одновременно может работать браузер, текстовый редактор, музыкальный проигрыватель. На экране дисплея открываются несколько окон, каждое из которых связано со своим работающим процессом.

Если на компьютере только один процессор, то он переключается с одного процесса на другой, создавая видимость одновременной работы. Переключение происходит по истечении одного или нескольких "тиков" (ticks). Размер тика зависит от тактовой частоты процессора и обычно имеет порядок 0,01 секунды. Процессам назначаются разные приоритеты (priority). Процессы с низким приоритетом не могут прервать выполнение процесса с более высоким приоритетом, они меньше занимают процессор и поэтому выполняются медленно, как говорят, "на фоне". Самый высокий приоритет у системных процессов, например, у диспетчера (scheduler), который как раз и занимается переключением процессора с процесса на процесс. Такие процессы нельзя прерывать, пока они не закончат работу, иначе компьютер быстро придет в хаотическое состояние.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37