Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Работа с файлами и каталогами




Создать объект класса File можно при помощи вызова одного из конструкторов:

public File(File dir, String name)

public File(String path);

public File(String path, String name);

Первый конструктор имеет можно указать отдельно каталог и имя файла, для которого создается объект; второй конструктор имеет один параметр - строку пути к каталогу или файлу; третий конструктор позволяет указать полный путь к каталогу и имя файла.

После создания объекта класса File нетрудно определить атрибуты этого объекта, воспользовавшись следующими методами этого класса:

· exist() - проверяет существование файла или каталога.

· canRead() - проверяет возможность чтения из файла.

· canWrite() - проверяет возможность записи в файл.

· isDirectory() - проверка того, соответствует ли созданный объект каталогу.

· isFile() - проверка того, соответствует ли созданный объект файлу.

· getName() - возвращает имя файла или каталога (выделяет его из полного пути).

· getAbsolutePath() - возвращает абсолютный путь к файлу или каталогу, который может быть машинно-зависимым.

· getPath() - позволяет определить машинно-независимый путь к файлу или каталогу.

· getParent() - определяет родительский каталог для объекта.

· length() - определяет длину файла в байтах.

· lastModified() - определяет время последней модификации файла или каталога (выдает время в относительных единицах с момента запуска системы).

С помощью методов mkdir() и mkdirs() можно создавать новые каталоги. Первый из них создает один каталог, второй - все подкаталоги, ведущие к создаваемому каталогу.

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

Для сравнения объектов класса File можно воспользоваться методом equals(). Нужно только отметить, что этот метод сравнивает пути к файлам и каталогам, но не сами файлы и каталоги.

Для получения списка содержимого каталога, соответствующего созданному объекту класса File, следует воспользоваться методом list(). Один вариант этого метода возвращает массив строк с именами содержимого каталога. Второй позволяет получить список не всех объектов, хранящихся в каталоге, а только тех, что удовлетворяют условиям, определенным в передаваемом этому методу фильтре FilenameFilter.

Перед тем, как передать методу list() фильтр, этот фильтр необходимо создать. Сначала необходимо определить новый класс, реализующий интерфейс FilenameFilter, переопределив в нем метод accept() класса FilenameFilter. В этом методе определяется, какие файлы будут выбираться из общего списка. Если имя файла подходит критерию отбора, то метод accept() должен возвратить значение true, если не подходит - значение false. Например, создадим класс, определяющий фильтр на основе расширения файла:

public class ExtFilter implements FilenameFilter

{ private String extension; // для хранения строки вида ".ext"

public ExtFilter(String ext); // e - расширение файла

{ extension="."+ext; // формирование строки

}

public boolean accept(File dir,String fileName)

{ // return true - для файлов, удовлетворяющих условию,

// иначе - return false

return(fileName.endsWith(extension); // только для файлов *.ext,

}

}

Передавая затем объект класса фильтров методу list() класса File, можно получить отфильтрованные элементы каталога, например:

ExtFilter txtFiles=new ExtFilter("txt"); // объект-фильтр

File dir=new File("\\tmp\\example"); // объект-каталог

// получение списка файлов с расширением.txt

String d[]=dir.list(txtFiles);

for(int i=0; i<d.length; i++) System.out.println("\t"+d[i]);

3.2 Приложение DirList

Задание. Создать автономное приложение DirList, в окне которого содержится текстовая область, в которой выводится список всех файлов и каталогов, расположенных в заданном каталоге. Имена файлов выводятся строчными буквами, а имена каталогов - прописными.

Методические указания. Приложение должно быть создано на основе шаблона, содержащегося в Приложении 7.

Конструктор класса фрейма (метод MainWndFrame()).

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

TextArea text; // текстовая область

File dir; // объект, ассоциированный с каталогом

String[] dirList; // список файлов и каталогов

File file; // объект, ассоциированный с файлом

В качестве поля редактирования создадим текстовую область text при помощи оператора new, установим для этой области запрет на редактирование методом setEditable(), а затем добавим эту область в центральную часть фрейма методом add().

Создадим объект класса File для каталога "c:" и ссылку на этот объект присвоим переменной dir. При помощи метода list() получим список dirList всех файлов и каталогов каталога dir.

Далее в цикле по i (i от 0 до dirList.length): создадим объект file, передавая конструктору строку dir.getPath()+"\\"+dirList[i] (полное имя каждого пункта списка); если объект file является файлом (проверяется при помощи метода isFile()), то добавить в текстовую область text имя файла строчными буквами, иначе - вывести имя каталога прописными буквами, например:

text.appendText(dirList[i].toLowerCase()+"\r\n");

3.3 Произвольный доступ к файлам

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

Библиотека классов Java содержит класс RandomAccessFile, который предназначен специально для организации прямого доступа к файлам как для чтения, так и для записи. Этот класс позволяет считывать данные из файла прямо в массивы, строковые переменные и переменные примитивных типов Java, причем данные в файл можно записывать в обратном порядке.

Класс RandomAccessFile можно создать с помощью либо объектов File, либо переменной типа String, в которой описывается путь к файлу:

public RandomAccessFile(File file, String mode);

public RandomAccessFile(String name, String mode);

При создании объекта RandomAccessFile указывается режим работы с файлом: читать файл или читать и записывать. Файл открывается на чтение и/или запись после реализации объекта RandomAccessFile. Открыв файл, можно читать или писать данные одним из простейших способов - либо байт за байтом, либо строку за строкой. Так же как и все методы класса File, каждый метод класса RandomAccessFile вызывает исключение IOException.

Позиционирование внутри файла обеспечивается методом seek(), в качестве параметра которому передается абсолютное смещение внутри файла. После вызова этого метода текущая позиция в файле устанавливается в соответствии с переданным параметром.

В любой момент можно определить текущую позицию внутри файла, вызвав функцию getFilePointer().

Еще один метод, имеющий отношение к позиционированию, называется skipBytes() - он продвигает текущую позицию в файле на заданное количество байт вперед.

Дескриптор файла можно определить с помощью метода getFD(), а длину файла в байтах - методом length().

Ряд методов предназначен для выполнения как обычного, так и форматированного ввода из файла. Этот набор аналогичен методам, определенным для потоков:

public int read();

public int read(byte b[]);

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

public final boolean readBoolean();

public final byte readByte();

public final char readChar();

public final double readDouble();

public final float readFloat();

public final void readFully(byte b[]);

public final void readFully(byte b[], int off, int len);

public final int readInt();

public final String readLine();

public final long readLong();

public final short readShort();

public final int readUnsignedByte();

public final int readUnsignedShort();

public final String readUTF();

Существуют также методы, позволяющие выполнять обычную или форматированную запись в файлы с прямым доступом:

public void write(byte b[]);

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

public void write(int b);

public final void writeBoolean(boolean v);

public final void writeByte(int v);

public final void writeBytes(String s);

public final void writeChar(int v);

public final void writeChars(String s);

public final void writeDouble(double v);

public final void writeFloat(float v);

public final void writeInt(int v);

public final void writeLong(long v);

public final void writeShort(int v);

public final void writeUTF(String str);

3.4 Просмотр локальной файловой системы

Для того, чтобы позволить пользователю просматривать локальную файловую систему, предназначен класс FileDialog пакета java.awt, который создает экземпляр диалогового окна. Этот класс закрыт для апплетов; им совершенно незачем иметь доступ к файловой системе локального компьютера, на который они загружены. Самостоятельные же приложения могут использовать класс FileDialog.

Методы класса FileDialog

· FileDialog(Frame parent, String title) - Конструктор, создает экземпляр класса, режим по умолчанию (FileDialog.LOAD)

· FileDialog(Frame parent, String title,int mode) - Конструктор, создает экземпляр класса, режим задается (FileDialog.LOAD или FileDialog.SAVE)

· getMode - Поучение режима диалога

· setDirectory - Задает каталог диалога

· setFile - При вызове до начала изображения диалога задает файл по умолчанию для диалога

· getFile - Получает имя определенного файла

· getDirectory - Получает имя каталога диалога

· setFilenameFilter - Устанавливает фильтр имени файла

· getFilenameFilter - Получает фильтр имени файла

Пользоваться классом FileDialog достаточно легко, его единственная задача - снабдить пользователя стандартным модальным диалоговым окном для просмотра файлов. Когда эта задача выполнена, применяется метод getFile(), чтобы получить имя файла, и метод getDirectory(), чтобы получить путь к файлу. Фактически файловый диалог не касается непосредственно системы файлов; он только делает доступным то, что выбрал пользователь.

Рассмотрим примеры использования класса FileDialog. Пусть в классе фрейма необходимо вызвать файловый диалог, тогда можно использовать следующие фрагменты кода:

// создание объекта и его использование

FileDialog dlg=new FileDialog(this,"Open File",FileDialog.LOAD);

dlg.setFile("*.txt"); // установка имени файла по умолчанию

if(!isVisible()) show(); // родительский фрейм должен быть видимым

dlg.show(); // отображение диалога

String path=dlg.getDirectory()+dlg.getFile(); // получить имя файла

// теперь можно создать входной поток, связанный с файлом,

// или создать объект класса RandomAccessFile для чтения

или

// создание объекта и его использование

FileDialog dlg=new FileDialog(this,"Save File",FileDialog.SAVE);

if(!isVisible()) show(); // родительский фрейм должен быть видимым

dlg.setFile("*.txt"); // установка имени файла по умолчанию

dlg.show(); // отображение диалога

String path=dlg.getDirectory()+dlg.getFile(); // получить имя файла

// теперь можно создать выходной поток, связанный с файлом,

// или создать объект класса RandomAccessFile для записи

Следует обратить внимание на проверку того, виден ли фрейм-родитель до отображения диалога: как и при работе со всеми диалоговыми окнами, фрейм-родитель должен быть активным до того, как производится попытка показать диалоговое окно.

Кроме установки режима можно изменить и поведение диалогового окна, задав FilenameFilter перед тем как диалог появится на экране. После создания нового класса и реализации в нем интерфейса FilenameFilter, объект этого класса можно передать классу FileDialog методомsetFilenameFilter(), Этим можно ограничить выбор тех файлов, которые FileDialog предоставляет пользователю.

3.5 Приложение FileDialogDemo

Задание. На основе приложения StreamDemo создать автономное приложение FileDialogDemo, в котором имя файла для чтения и записи содержимого области редактирования не задается статически в приложении, а выбирается пользователем при помощи соответствующих файловых диалогов. Для операций записи и чтения в файл использовать класс RandomAccessFile.

Методические указания. Приложение должно быть создано на основе приложения StreamDemo.

Обработка событий (метод handleEvent()).

При обработке событий от меню добавить выбор имени файла для открытия и выбор имени файла для сохранения (для этого использовать объекты класса FileDialog). Полученные от диалогов полные имена выбранных файлов сохранять в переменной path класса String.

Для чтения и записи в файл использовать не потоки dataIn и dataOut классов DataInputStream и DataOutputFile соответственно, а потоки dataIn и dataOut класса RandomAccessFile. Конструктору этого класса следует передать имя файла path и режим работы с файлом (чтение/запись) в соответствии с обрабатываем событием.

При записи в файл необходимо удалить вызов метода flush() для объекта dataOut, так как метод с таким именем отсутствует в классе RandomAccessFile.

Задания к лабораторной работе

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

Задание 2. Создать приложения StreamDemo, DirList, FileDialogDemoи объяснить их работу.

Задание 3. Дать ответы на контрольные вопросы.

Контрольные вопросы

1. Какие ограничения накладываются на апплеты при работе с файлами?

2. Что необходимо сделать для создания автономного Java-приложения?

3. Как организовать графический интерфейс пользователя в самостоятельных приложениях?

4. С какими потоками может работать Java-приложение?

5. Какие существуют базовые классы Java для работы с потоками и файлами?

6. Какие классы Java являются производными от класса InputStream?

7. Какие классы Java являются производными от класса OutputStream?

8. Какие стандартные потоки ввода-вывода существуют в Java, каково их назначение? На базе каких классов создаются стандартные потоки?

9. Чем является поток System.in? Какими методами чаще всего пользуются при работе с этим потоком?

10. Чем является поток System.out? Какими методами чаще всего пользуются при работе с этим потоком?

11. Чем является поток System.err? Какими методами чаще всего пользуются при работе с этим потоком?

12. В чем заключается особенность создания потока, связанного с локальным файлом?

13. Как создать поток для форматированного обмена данными, связанного с локальным файлом?

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

15. Выполняется ли процессом «сборки мусора» автоматическое закрытие потоков, с которыми приложение завершило работу?

16. За счет чего буферизация ускоряет работу приложений с потоками?

17. Когда применяется принудительный сброс буферов?

18. В каких случаях чаще всего используются потоки в оперативной памяти?

19. Для выполнения каких операций применяется класс File?

20. Для чего применяются фильтры файлов и как создать и использовать фильтр?

21. Для чего предназначен класс RandomAccessFile? Чем он отличается от потоков ввода и вывода?

 

ЛАБОРАТОРНАЯ РАБОТА №8

СЕТЕВЫЕ ПРИЛОЖЕНИЯ: ПЕРЕДАЧА ДАННЫХ С ИСПОЛЬЗОВАНИЕМ СОКЕТОВ (2 ЧАСА)

МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ЛАБОРАТОРНОЙ РАБОТЕ

Сетевые классы, содержащиеся в API (пакет java.net), можно разделить на две основные группы: классы, занимающиеся сокетами, и классы, занимающиеся URL. В данной главе будет обсуждаться первая группа классов.

1. Сокеты

В библиотеке классов Java есть очень удобное средство, с помощью которого можно организовать взаимодействие между приложениями Java, работающими как на одном и том же, так и на разных узлах сети. Это средство - так называемые сокеты.

Сокеты можно представить в виде двух розеток, в которые включен провод, предназначенный для передачи данных через сеть. В компьютерной терминологии - сокеты - это программный интерфейс, предназначенный для передачи данных между приложениями. Сокеты не реализуют метод передачи данных - они создают экземпляры более общих классов ввода/вывода, называемых потоками (thread), которые выполняют эту работу. Сокет переносит данные по сети; потоки занимаются тем, что закладывают данные в сокет и выдают их наружу.

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

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

Потоковые сокеты позволяют передавать данные только между двумя приложениями, так как они предполагают создание канала между эти двумя приложениями. Однако иногда нужно обеспечить взаимодействие нескольких клиентских приложений с одним сервером. В этом случае можно создавать в серверном приложении отдельные задачи и отдельные каналы для каждого клиентского приложения, либо воспользоваться датаграммными сокетами - они позволяют передавать данные всем узлам сети.

Для передачи данных через датаграммные сокеты не нужно создавать канал - данные непосредственно посылаются тому приложению, для которого они предназначены, с использованием адреса этого приложения в виде сокета и номера порта. При этом одно клиентское приложение может обмениваться данными с несколькими серверными приложениями или, наоборот, одно серверное приложение - с несколькими клиентскими.

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

Причина отсутствия такой гарантии доставки данных при использовании датаграммных сокетов заключается в использовании такими сокетами протокола с негарантированной доставкой UDP. Потоковые сокеты работают через протокол гарантированной доставки TCP.

2. Протокол TCP/IP, адрес IP и класс InetAddress

Идея сокетов неразрывно связана с TCP/IP (Transmission Contol Protocol/ Internet Protocol - Протокол контроля передачи/Межсетевой протокол Интернет) - протоколом, использующимся в Internet. По существу сокет является непрерывной связью данных между двумя хостами сети (все компьютеры, подключенные к сети, называются узлами или хостами (host)). Сокет определяется сетевым адресом конечного компьютера (endpoint), а также портом на каждом хосте. Компьютеры в сети направляют приходящие из сети потоки данных в специальные принимающие программы, присваивая каждой программе отдельный номер. - порт программы. Аналогично, когда генерируются выходные данные, программе, инициализирующей передачу данных, присваивается номер порта для транзакции. В TCP/IP резервируются определенные номера портов для специальных протоколов - например, 25 для SMTP и 80 для HTTP. Все номера портов, меньшие 1024, зарезервированы на каждом хосте для системного администратора.

Каждый хост в сети, осуществляющей связь по протоколу TCP/IP (в том числе и Internet) присвоен уникальный численный идентификатор, называемый IP-адресом. IP-адрес состоит из четырех десятичный чисел в диапазоне от 0 до 255 и в общем случае представляется числом с точками - например, 194.84.124.60.

Фактически адрес IP является 32-разрядным числом (4 байта), а упомянутые числа представляют собой отдельные байты адреса IP.

Так как работать с цифрами удобно только компьютеру, была придумана система доменных адресов (система DNS - Domain Name System). При использовании этой системы адресам IP ставится в соответствие так называемый доменный адрес, такой, как www.vvsu.ru. Человек задает имя хоста, и его компьютер запрашивает местный DNS-сервер, который определяет по данному имени IP-адрес.

Для работы с IP-адресами в библиотеке классов Java имеется класс InetAddress. Заметим, что при создании сокета можно задавать либо имя хоста в форме строки, либо IP-адрес в форме InetAddress. InetAddress для созданного уже сокета можно определить при помощи метода getInetAddress() класса сокетов Socket. Знать этот адрес бывает полезно, например, при необходимости открытия нового соединения с той же машиной. Тогда немного быстрее будет вместо имени хоста воспользоваться InetAddress, чтобы избежать дополнительного преобразования DNS.

Рассмотрим наиболее интересные методы класса InetAddress. Прежде всего необходимо создать объект класса InetAddress. Эта процедура выполняется не с помощью оператора new, а с применением статических методов getLocalHost(), getByName() и getAllByName.

Создание объекта класса InetAddress для локального узла

Метод getLocalHost() создает объект класса InetAddress для локального узла, то есть для той рабочей станции, на которой выполняется приложение Java. Так как этот метод статический, то его можно вызывать, используя имя класса InetAddress:

InetAddress iaLocal;

iaLocal=InetAddress.getLocalHost();

Создание объекта класса InetAddress для удаленного узла

В том случае, когда интерес представляет удаленный узел сети Internet или корпоративной сети Intranet, объект класса InetAddress для него можно создать с помощью методов getByName() или getAllByName(). Первый из них возвращает по имени узла узла, а второй - массив всех адресов IP, связанных с данным узлом. Если узла с таким не существует, при выполнении обоих методов возникает исключение UnknownHostException.

Методам getByName() или getAllByName() можно передавать не только имя узла, такое, как например www.vvsu.ru, но и строку адреса IP в виде четырех десятизначных чисел, разделенных точками.

Другие методы класса InetAddress

После создания объекта класса для локального или удаленного узла можно использовать и другие методы класса InetAddress.

Метод getAddress() возвращает массив из четырех байт IP-адреса объекта. Байт с нулевым индексом массива возвращает старший байт адреса IP.

С помощью метода getHostName можно определить имя узла, для которого был создан объект класса InetAddress.

Метод toString() возвращает текстовую строку, которая содержит имя узла, разделитель / и адрес IP в виде четырех десятичных чисел, разделенных точками.

Метод equals() предназначен для сравнения адресов IP как объектов класса InetAddress.

3. Потоковые сокеты

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

3.1 Создание и использование канала передачи данных

Рассмотрим процесс создания канала в деталях.




Поделиться с друзьями:


Дата добавления: 2014-11-20; Просмотров: 555; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.563 сек.