Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык программирования JAVA.pdf
Скачиваний:
373
Добавлен:
02.05.2014
Размер:
2.57 Mб
Скачать

converted to PDF by BoJIoc

11.16.1. Классы потоков данных

Для каждого интерфейса Data имеется соответствующий поток. Кроме того, класс RandomAccessFile реализует оба интерфейса для входных и выходных потоков данных (см. раздел Класс RandomAccessFile”). Каждый из классов Data представляет собой расширение класса Filter, так что потоки данных могут использоваться для фильтрации других потоков. Следовательно, каждый из них должен иметь конструкторы, которые получают в качестве параметра другой входной или выходной поток. Например, фильтрация может применяться при записи данных в файл для этого следует создать объект DataOutputStream до объекта FileOutputStream, а затем, при считывании данных из файла, поместить DataInputStream перед объектом FileInput Stream.

Упражнение 11.7

Включите в класс Body из главы 2 метод, который записывает содержимое объекта в DataOutputStream, и конструктор, который считывает состояние объекта из

DataInputStream.

11.17. Класс RandomAccessFile

Класс RandomAccessFile предоставляет более совершенный механизм для работы с файлами, чем файловые потоки. Он не является расширением Input Stream или OutputStream, поскольку может осуществлять любую из операций чтения/записи или оба действия сразу. Режим работы с файлом указывается в качестве параметра для различных конструкторов. Класс Random AccessFile реализует оба интерфейса Data InputStream и DataOutput Stream, поэтому он может применяться для чтения/записи встроенных типов Java.

Хотя класс RandomAccessFile не является расширением входных и выходных потоковых классов, имена и сигнатуры содержащихся в нем методов совпадают с вызовами read и write. Хотя это означает, что вам не придется учить новый набор имен и семантик для выполнения той же самой задачи, объекты класса RandomAccessFile не могут использоваться там, где требуется присутствие объектов InputStream или OutputStream. Тем не менее вы можете использовать объекты RandomAccessFile вместо объектов-потоков

DataInput или DataOutput.

Класс RandomAccessFile содержит три конструктора:

public RandomAccessFile(String name, String mode)

throws IOException

Создает объект RandomAccessFile для заданных имени файла и режима. Режим указывается в виде “r” или “rw” для доступа по чтению или чтению/записи соответственно. Любое другое значение режима приводит к возбуждению I OException.

public RandomAccessFile(File file, String mode)

throws IOException

Создает объект RandomAccessFile для заданного объекта класса File и режима.

public RandomAccessFile(FileDescriptor fd) throws IOException

Создает объект RandomAccessFile для заданного объекта fd типа File Descriptor (см. раздел

Файловые потоки и FileDescriptor”).

Термин произвольный доступ” (random access), вынесенный в название типа, обозначает возможность установки файлового указателя чтения/записи в любую позицию внутри файла с последующим выполнением нужной операции. Эта возможность обеспечивается следующими методами:

public long getFilePointer() throws IOException

converted to PDF by BoJIoc

Возвращает текущее смещение (в байтах) от начала файла.

public void seek(long pos) throws IOException

Устанавливает файловый указатель в заданную позицию (в байтах). Следующий считанный или записанный байт будет иметь смещение pos.

public long length() throws IOException

Возвращает длину файла.

Упражнение 11.8

Напишите программу для чтения файла, который состоит из отдельных элементов, разделяемых строками, начинающимися с символов %%. Программа должна создавать сводный файл, содержащий начальную позицию для каждого такого элемента. Затем напишите программу, которая печатает случайный элемент на основании сводного файла (см. описание метода Math.random в разделе Класс Math”).

11.18. Класс File

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

Объект File обычно связан с полным именем файла, причем необязательно существующего. Например, чтобы выяснить, представляет ли некоторое имя существующий в системе файл, следует сначала создать объект File для данного имени, после чего вызвать для этого объекта метод exists.

Полное имя /В этом разделе следует отличать полное имя файла от имени объекта класса файл. - Примеч. перев./ делится на две части: одна определяет каталог (или папку), а другая собственно файл. Для разделения компонентов пути служит символ, хранящийся как значение типа char в статическом поле separatorChar или значение типа String в статическом поле separator. Последнее вхождение этого символа в путь отделяет каталог от имени файла.

Объекты File создаются одним из трех конструкторов:

public File(String path)

Создает объект File для работы с заданным файлом path. Если параметр равен null, возбуждается исключение NullPointerException.

public File(String dirName, String name)

Создает объект File для работы с файлом name, находящимся в каталоге dirName. Если параметр dirName равен null, используется только компонент name. В противном случае вызов конструктора эквивалентен следующему:

File(dirname + File.separator + name)

public File(File fileDir, String name)

Создает объект File для заданного объекта-каталога fileDir типа File и файла с именем name. Вызов конструктора эквивалентен следующему:

File(fileDir.getPath(), name)

converted to PDF by BoJIoc

Четыре метода get предназначены для получения информации о компонентах полного имени объекта File. В приведенном ниже фрагменте программы вызывается каждый из этих методов:

File src = new File("ok", "FileMethods"); System.out.println("getName() = " + src.getName()); System.out.println("getPath() = " + src.getPath()); System.out.println("getAbsolutePath() = "

+ src.getAbsolutePath()); System.out.println("getParent() = " + src.getParent());

Вот как выглядит результат работы программы:

getName() = FileMethods

getPath() = ok/FileMethods

getAbsolutePath() = /vob/java_prog/src/ok/FileMethods

getParent() = ok

Несколько методов возвращают логические значения, которые характеризуют файл, представленный объектом File:

exists: возвращает true, если файл существует в файловой системе.

canRead: возвращает true, если файл существует и доступен для чтения.

canWrite: возвращает true, если файл существует и доступен для записи.

isFile: возвращает true, если файл существует и является обычным (то есть не каталогом или файлом особого типа).

isDirectory: возвращает true, если файл является каталогом.

isAbsolute: возвращает true, если путь представляет собой полное имя файла.

Класс File содержит и другие полезные методы:

public long lastModified()

Возвращает дату последней модификации файла. Возвращаемое значение должно

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

public long length()

Возвращает длину файла в байтах.

public boolean mkdir()

Создает каталог и возвращает true в случае успеха.

public boolean mkdirs()

Создает все каталоги, входящие в заданный путь, и возвращает true в случае успеха. Метод обеспечивает возникновение конкретного каталога, даже если для этого потребуется создать другие, не существующие в данный момент каталоги, которые находятся выше в иерархии.

converted to PDF by BoJIoc

public boolean renameTo(File new_name)

Переименовывает файл и возвращает true в случае успеха.

public boolean delete()

Удаляет файл или каталог, представленный объектом File, и возвращает true в случае успеха.

public String[] list()

Возвращает список файлов в каталоге. Если объект File представляет собой не каталог, а нечто иное, передается null; в противном случае возвращается массив с именами файлов. Список содержит все файлы каталога, за исключением эквивалентов “.” и “..” (текущий и родительский каталоги соответственно).

public String[] list(FilenameFilter filter)

Использует заданный фильтр для составления списка файлов в каталоге (см. ниже раздел

Интерфес Filename Filter”).

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

Для создания файлов используются объекты классов FileOutputStream или

RandomAccessFile, а не объекты класса File.

Наконец, остается упомянуть, что символ File.pathSeparatorChar и строка File.pathSeparator представляют символ, разделяющий каталоги или файлы в полном имени. Например, в системе UNIX для разделения компонентов полного имени используется двоеточие: “.:/bin:/usr/bin”. Следовательно, в системе UNIX символ pathSepar a torChar представляет собой двоеточие.

Полное имя файла хранится в защищенном строковом поле с именем String. Подклассы File могут при необходимости непосредственно обращаться к этому полю или модифицировать его.

Упражнение 11.9

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

11.19. Интерфейс FilenameFilter

Интерфейс FilenameFilter позволяет создавать объекты, которые фильтруют списки файлов и удаляют из них ненужные. Он содержит всего один метод:

boolean accept(File dir, String name)

Возвращает true, если файл с именем name в каталоге dir должен входить в отфильтрованный список.

В следующем примере объект FilenameFilter используется для того, чтобы в список включались только каталоги:

import java.io.*;

class DirFilter implements FilenameFilter {

converted to PDF by BoJIoc

public boolean accept(File dir, String name) { return new File(dir, name).isDirectory();

}

public static void main(String[] args) { File dir = new File(args[0]);

String[] files = dir.list(new DirFilter()); System.out.println(files.length + "dir(s):"); for (int i = 0; i << files.length; i++)

System.out.println("\t" + files[i]);

}

}

Сначала мы создаем объект File, который представляет собой каталог, указанный в командной строке. Затем мы конструируем объект DirFilter и передаем его в качестве параметра методу list. Для каждого имени, входящего в каталог, list вызывает метод accept объекта-фильтра и включает имя в список лишь в том случае, если объект-фильтр возвращает true. Для нашего метода accept значение true показывает, что имя соответствует каталогу.

Упражнение 11.10

С помощью интерфейса FilenameFilter напишите программу, которая получает в качестве

параметров имя каталога и расширение файла и выводит список всех файлов каталога с заданным расширением.

11.20. Классы IOException

Для сообщений обо всех ошибках ввода/вывода, обнаруженных классами пакета java.io, должны использоваться исключения, являющиеся подклассом IOException. Большинство классов проектировалось для целей общего назначения, так что основная часть исключений также носит универсальный характер. Например, методы класса InputStream, возбуждающие IOException, не могут заранее предсказать, какие именно возникнут исключения, так как каждый конкретный потоковый класс может возбудить некоторый подкласс IOException, сигнализируя тем самым об ошибке, относящейся лишь к этому потоку. Например, фильтрующие входные и выходные потоки лишь передают без обработки исключения от объектов, на основе которых они создавались и которые могут представлять собой потоки любого типа.

В пакете java.io используются четыре подкласса IOException:

EOFException extends IOException

Возбуждается интерфейсами потоков данных при достижении конца ввода, как запланированном, так и неожиданном.

FileNotFoundException extends IOException

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

InterruptedIOException extends IOException

Возбуждается любым потоком, когда в операцию ввода/вывода вмешивается прерывание программного потока (см. раздел Прерывание потока”). Фактически операции ввода/вывода переводят исключение InterruptedException в InterruptedIO Exception.

UTFDataFormatException extends IOException