2a9cfd0b

В этом приложении мы создаем


В этом приложении мы создаем на базе класса Thread два класса, один из которых предназначен для создания задачи рисования прямоугольников, а другой - для создания задачи рисования закрашенных эллипсов.
Что же касается основного класса аплета, то он унаследован, как обычно, от класса Applet и не реализует интерфейс Runnable.


Структура приложения Standard очень проста. В нем определен один класс с именем Standard типа public, и один метод с имененм main:
public class Standard
{
  public static void main(String args[])
  {
    . . .
  }
}
Напомним, что имена класса и файла .class должны совпадать.
Сразу после запуска автономного приложения Java управление передается функции main.
Внутри этой функции мы определили массив bKbdInput типа byte и строку sOut:
byte bKbdInput[] = new byte[256];
String sOut;
Созданный оператором new массив имеет размер 256 байт и предназначен для хранения строки, введенной пользователем при помощи клавиатуры. В дальнейшем содержимое этого массива преобразуется в строку sOut.
Первое, что делает наше приложение после создания массива, это вывод на консоль текстовой строки приглашения:
System.out.println("Hello, Java!\n" +


  "Enter string and press <Enter>...");
Здесь вызывается метод println для статического объекта out класса PrintStream, который, как вы знаете, определен в классе System.
На следующем этапе приложение читает из стандартного потока ввода in, вызывая для этого метод read:
System.in.read(bKbdInput);
Стандартный поток ввода связан с клавиатурой, поэтому приложение перейдет в состояние ожидания до тех пор, пока пользователь не введет текстовую строку, нажав после чего клавишу <Enter>.
Введенная строка отображается на консоли, для чего она записывается в стандартный поток вывода методом println:
System.out.println(sOut);
При выполнении операций с потоками ввода или вывода могут возникать исключения, поэтому в нашем приложении предусмотрены обработчики исключений:
catch(Exception ioe)
{
  System.err.println(ioe.toString());
}
При возникновении любого исключения в стандартный поток вывода сообщений об ошибках записывается текстовая строка названия класса возникнувшего исключения.
Для того чтобы вы смогли посмотреть на результаты работы приложения, после отображения на консоли введенной строки приложение вновь вызывается метод read для стандартного потока ввода. Для завершения работы приложения пользователь должен нажать клавишу <Enter>.


После ввода текстовой строки и ее записи в поле sOut наше приложение создает на базе этой строки объект st класса StringTokenizer:
StringTokenizer st;
st = new StringTokenizer(sOut, ",.; ");
Далее он в цикле получает все элементы строки, вызывая для этого метод nextElement:
while(st.hasMoreElements())
{
  str = new String((String)st.nextElement());
  System.out.println(str);
}
Для проверки условия завершения цикла вызывается метод hasMoreElements. Когда он возвращает значение false, цикл завершается.
Выделенные в цикле элементы строки записываются в переменную str и отображаются на консоли.


После ввода с клавиатуры пути к файлу или каталогу приложение записывает введенный путь в строку sFilePath класса String.
Так как в этой строке имеется символ конца строки, нам нужно его отрезать. Для этого мы воспользуемся классом StringTokenizer, задав для него в качестве разделителя символ конца строки:
StringTokenizer st;
st = new StringTokenizer(sFilePath, "\r\n");
sFilePath = new String((String)st.nextElement());
Первый же вызов метода nextElement возвращает нам строку пути, которую мы и сохраняем в поле sFilePath.
Далее мы создаем объект класса File, передавая конструктору этого класса строку sFilePath:
File fl = new File(sFilePath);
Так как при вводе пути файла или каталога вы можете допустить ошибку, приложение, прежде чем продолжать свою работу, проверяет существование указанного файла или каталога. Для проверки вызывается метод exists, определенный в классе File:
if(!fl.exists())
{     
  System.out.println("File not found: " + sFilePath);
}
На следующем этапе приложение проверяет, является ли объект класса File каталогом, вызвая метод isDirectory:
if(fl.isDirectory())
  System.out.println("File " + sFilePath + " is directory");
Аналогичная проверка выполняется методом isFile на принадлежность объекта к файлам:
else if (fl.isFile())
  System.out.println("File " + sFilePath + " is file");
На последнем этапе приложение определяет различные атрибуты файла или каталога, вызывая соответствующие методы класса File:
System.out.println(
  "Parent: " + fl.getParent() +
  "\nLength: " + fl.length()    +
  "\nRead op. available: " + fl.canRead() +
  "\nWrite op. available: " + fl.canWrite());
Параметры отображаются на консоли методом println.


В начале своей работы приложение вводит с клавиатуры путь к каталогу и отрезает из полученной строки символ новой строки, пользуясь для этого классом StringTokenizer:
System.out.println("Enter directory path...");
System.in.read(bKbdInput);
sDirPath = new String(bKbdInput, 0);
StringTokenizer st;
st = new StringTokenizer(sDirPath, "\r\n");
sDirPath = new String((String)st.nextElement());
Строка пути записывается в поле sDirPath.
Аналогичным образом вводится и обрабатывается маска, которая записывается в поле sMask.
Далее создается объект класса File, соответствующий каталогу sDirPath, содержимое которого нужно просмотреть:
File fdir = new File(sDirPath);
После этого выполняется проверка существования пути, а также проверка, указывает ли этот путь на каталог. Для проверки мы применяем методы exists и isDirectory, рассмотренные ранее.
Если все нормально, и был указан существующий каталог, приложение анализирует поле маски sMask. В случае пустой маски для получения содержимого каталога мы вызваем метод list без параметров:
if(sMask == null)
  dirlist = fdir.list();
Если же маска определена, вызывается второй вариант этого же метода:
else
  dirlist = fdir.list(new MaskFilter(sMask));
Здесь в качестве параметра методу list мы передаем вновь созданный объект класса MaskFilter (фильтр), передав соответствующему конструктору строку маски.
В любом случае метод list заполняет полученным списком массив строк dirlist. Содержимое этого массива перебирается в цикле:
for (int i = 0; i < dirlist.length; i++)
{
  File f = new File(sDirPath + "\\" + dirlist[i]);
  if(f.isFile())
    System.out.println(dirlist[i].toLowerCase());
  else
    System.out.println(dirlist[i]);
}
Для каждого элемента массива мы создаем объект класса File, передавая конструктору путь каталога, добавив к нему разделитель и строку элемента массива. Затем если данная строка соответсвует файлу, а не каталогу, имя выводится строчными буквами. Для преобразования мы вызываем метод toLowerCase, определенный в классе String.


Сразу после запуска приложение запрашивает с консоли текстовую строку адреса URL файла, который необходимо переписать через сеть на локальный диск. После удаления символа перевода строки адрес записывается в поле sURL.
Далее приложение создает объект класса URL, соответствующий введенному адресу:
u = new URL(sURL);
На следующем этапе для объекта URL создается входной поток, для чего вызывается метод openStream:
InputStream is = u.openStream();
Идентификатор этого потока сохраняется в поле is.
Принятый файл будет записан в текущий каталог под именем output.dat. Для этого мы создаем входной буферизованный форматированный поток os, как это показано ниже:
DataOutputStream os = new DataOutputStream(
  new BufferedOutputStream(
  new FileOutputStream("output.dat")));
После знакомства с главой нашей книги, посвященной работе с потоками, эти строки не должны вызывать у вас никаких вопросов.
Операция чтения данных из входного потока и записи в выходной поток выполняется в цикле:
while(true)
{
  int nReaded = is.read(buf);
  if(nReaded == -1)
    break;
  os.write(buf, 0, nReaded);
}
Вначале для входного потока вызывается метод read. Он возвращает количество прочитанных байт данных или значение -1, если был достигнут конец потока. В последнем случае цикл прерывается.
Принятые данные размещаются в массиве buf, откуда затем они записываются в выходной поток методом write. Мы записываем в выходной поток столько байт данных, сколько было считано.
После того как файл будет принят и записан в выходной поток, мы закрываем оба потока:
is.close();
os.close();


Приложение ShowChart получает содержимое файла исходных данных для построения круговой диаграммы с помощью класса URL. Как вы увидите, для получения содержимого этого файла оно не создает поток ввода явным образом, как это делало предыдущее приложение (хотя могло бы). Вместо этого оно пользуется методом getContent, определенным в классе URL.

Содержание раздела