Главная страница
Навигация по странице:

  • Индивидуальные задания

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

  • Рекомендуемая литература

  • Лабораторная работа 1 2 лабораторная работа 2 31 лабораторная работа 3 44 лабораторная работа 4 74


    Скачать 1.76 Mb.
    НазваниеЛабораторная работа 1 2 лабораторная работа 2 31 лабораторная работа 3 44 лабораторная работа 4 74
    Дата12.03.2021
    Размер1.76 Mb.
    Формат файлаdoc
    Имя файлаOOP_Lab_Rus.doc
    ТипЛабораторная работа
    #184105
    страница30 из 31
    1   ...   23   24   25   26   27   28   29   30   31

    ЛАБОРАТОРНАЯ РАБОТА 10.



    Тема: Классы java.io. Система ввода/вывода. Потоки данных. Работа с потоками.

    Цель: Научиться работать с пакетом, который поддерживает операции ввода-вывода.

    Теоретические сведения

    Классы пакета java.io.

    Рассматриваемые вопросы:

    10.1 Классы ввода-вывода. File

    10.2 Каталоги

    10.3 Использование FilenameFilter

    10.4 Создание каталогов

    10.5 Класс Stream

    10.5.1 Байтовые потоки

    10.5.2 Символьные потоки

    10.6 Использование потокового ввода-вывода

    10.7 Сериализация
    В пакете java.io присутствует множество классов и интерфейсов. Среди них - байтовые и символьные потоки, сериализация объектов (их сохранение и восстановление).

    Один из наиболее отличающихся классов ввода-вывода - Fi1e.
    10.1 Классы ввода-вывода. File

    Хотя большинство классов, определенных в java.io, работают с потоками, класс File этого не делает. Он имеет дело непосредственно с файлами и файловой системой. То есть класс File не указывает, как извлекается и сохраняется информация в файлах; он описывает свойства самих файлов. Объект File служит для получения и манипулирования информацией, ассоциированной с дисковым файлом, такой как права доступа, время, дата и путь к каталогу, а также для навигации иерархиями подкаталогов.

    File - первичный источник и место назначения для данных во многих программах. Хотя существует несколько ограничений в части использования файлов в аплетах (из соображений безопасности), тем не менее, они продолжают оставаться центральным ресурсом для хранения постоянной и разделяемой информации. Каталог в java трактуется как объект Fi1e с единственным дополнительным свойством: списком имен файлов, которые могут быть получены методом list ().

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

    File(String directorypath}

    File(String directorypath, String filename}

    File(File dirObj, String filename)

    File(URI uriObj)

    Здесь directorypath - имя пути файла, filename - имя файла или подкаталога, dirObj - объект File, указывающий каталог, а uriObj - объект URI, описывающий файл.

    В следующем примере создаются три файла: f1, f2 и fЗ. Первый объект File конструируется с путем к каталогу в единственном аргументе. Второй включает два аргумента - путь и имя файла. Третий включает путь, присвоенный f1, и имя файла; fЗ ссылается на тот же файл, что и f2.

    File fl = new File("/");

    File f2 = new File("/","autoexec.bat");

    File fЗ = new Fi1e(fl,"autoexec.bat");

    Fi1e определяет множество методов, представляющих стандартные свойства объекта File. Например, getName () возвращает имя файла, getparent () ­ имя родительского каталога, а exists () возвращает true, если файл существует, и fa1se - если нет. Однако класс Fi1e не симметричен. То есть в нем есть несколько методов, позволяющих проверять свойства простого файлового объекта, у которых нет дополняющих их методов изменения этих атрибутов. В следующем примере демонстрируется применение нескольких методов Fi1e.

    // Демонстрация работы с File.

    import java.io.File;

    class FileDemo {

    static void p(String s) {

    System.out.println(s);

    }

    public static void main(String args[]} {

    File f1 = new File("/java/COPYRIGHT");

    р ("Имя файла: " + fl. getName ( ) ) ;

    р("Путь: " + fl.getPath());

    р("Абсолютный путь: "+ fl.getAbsolиtePath());

    р("Родительский каталоI': " + fl.getParent());

    p(fl.exists() ? "существует" : "не существует");

    p(fl.canWrite() ? "доступен для записи" : "не доступен для записи");

    р (fl. canRead () ? "доступен для чтения" : "не доступен для чтения") ;

    р (fl. isDirectory () ? "является каталоI'ОМ" : "не является каталоI'ОМ");

    р (fl . isFile () ? "является обычным файлом" : "может быть именованным каналом") ;

    р (fl. isAbsolиte () ? "является абсолютным" : "не является абсолютным");

    р ("Время модификации: " + fl.1astModified () ) ;

    р("Размер: " + fl.1ength() + " байт");

    Запустив эту программу, вы увидите нечто вроде следующего:

    Имя файла: COPYRIGHT

    Путь: /java/COPYRIGHT

    Абсолютный путь: /java/COPYRIGHT

    Родительский каталог: /java

    существует

    доступен для записи

    доступен для чтения

    не является каталогом

    является обычным файлом

    является абсолютным

    Время модификации:. 812465204000

    Размер: 695 байт

    Большинство методов File самоочевидно. isFile() и isAbsolute() - нет. isFile() возвращает true, если вызывается с файлом, и false - если с каталогом. Также isFi1e() возвращает fa1se для некоторых специальных файлов, таких как драйверы устройств и именованные каналы, поэтому этот метод может применяться для того, чтобы убедиться, что данный файл действительно ведет себя как файл. Метод isAbso1ute() возвращает true, если файл имеет абсолютный путь, и fa1se - если относительный.

    Также Fi1e включает два полезных служебных метода. Первый из них, renameTo(), показан ниже:

    boolean renameTo(File пewNaтe)

    Здесь имя файла, указанное в параметре newName, становится новым именем вызывающего объекта File. Метод возвращает true в случае успеха и fa1se - в случае неудачи, если файл не может быть переименован (если вы либо пытаетесь переименовать файл так, например, что в результате он должен переместиться из одного каталога в другой, или же указываете имя существующего файла).

    Второй служебный метод - delete() , который удаляет дисковый файл, представленный путем вызывающего объекта Fi1e. Выrлядит он так:

    boolean delete()

    Также вы можете использовать метод de1ete () для удаления каталога, если он пуст. delete() возвращает true, если ему удается удалить файл, и false, если файл не может быть удален.
    10.2 Каталоги

    Каталоu - это объект File, содержащий список других файлов и каталогов. После создания объекта File, являющегося каталогом, его метод isDirectory() вернет true. В этом случае вы можете вызвать на этом объекте метод list(), чтобы извлечь список других файлов и каталогов, находящихся внутри него. Упомянутый метод имеет две формы. Вот первая из них:

    String [] list ()

    Список файлов возвращается в виде массива объектов String. Приведенная ниже программа иллюстрирует использование list() для просмотра содержимого каталога.

    // Использование каталогов.

    import java.io.File;

    class DirList {

    public static void main(String args[])

    String dirname = "/java";

    File fl = new File(dirname);

    if (fl.isDirectory()) {

    Sуstеm.оut.рrintln("Каталог " + dirname);

    String s[] = fl.1ist();

    for (int i=0; i < s.length; i++) {

    File f = new File(dirname + "/" + s[i]);

    if (f.isDirectory()) {

    System.out.println(s[i] + " является каталогом");

    else {

    System.out.println(s[i] +" является файлом"};

    }

    else {

    System. out. println (dirname + " is not а directory") ;

    }

    }

    }

    Ниже приведен вывод этой программы (Конечно, вывод, который вы увидите, будет отличаться, - в зависимости от того, что находится в каталоге)

    Каталог /java

    bin является каталогом

    lib является каталогом

    dеmо является каталогом

    COPYRIGHT является файлом

    README является файлом

    index.html является файлом

    include является каталогом

    src.zip является файлом

    src является каталогом
    10.3 Использование FilenameFilter

    Часто вам необходимо ограничить количество файлов, возвращенных методом list(), для включения только тех файлов, которые соответствуют определенному шаблону имен, или фильтру. Чтобы сделать это, необходимо использовать вторую форму list():

    String[] list(FilenameFilter FFObj)

    В этой форме FFObj - объект класса, реализующего интерфейс FilenameFilter.

    FilenameFilter определяет единственный метод accept() , вызываемый по одному разу с каждым файлом в списке. Ero общая форма такова:

    boolean accept(File directory, String filename)

    Метод accept() возвращает true для файлов каталоrа, указанноrо в directory, которые должны быть включены в список (то есть те, что соответствуют аргументу filename), и возвращает false для файлов, которые следует из списка исключить.

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

    import java.io.*;

    public class OnlyExt implements FilenameFilter

    String ext;

    public OnlyExt(String ext)

    this.ext = "." + ext;

    }

    public boolean accept(File dir, String name) {

    return name.endsWith(ext);

    }

    }

    Модифицированная программа просмотра листинга каталога показана ниже. Теперь она выведет только файлы с расширением .html.

    // Каталоr файлов .HTML.

    import java.io.*;

    class DirListOnly {

    public static void main(String args[])

    String dirname = "/java";

    File fl = new File(dirname);

    FilenameFilter only = new OnlyExt ("html") ;

    String s[] = fl.list(only);

    for (int i=0; i < s.length; i++)

    System.out.println(s[i]);

    }

    }

    }

    10.4 Создание каталогов

    Другими двумя полезными служебными методами File являются mkdir() и mkdirs() . Метод mkdir() создает каталог, возвращая true в случае успеха и false - в случае неудачи. Неудача говорит о том, что путь, указанный в объекте File, уже существует, или что каталог не может быть создан по причине того, что полный путь к нему еще не существует. Чтобы создать каталог, для которого путь еще не создан, используйте метод mkdirs(). Он создаст как сам каталог, так и всех его родителей.
    10.5 Класс Stream

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

    InputStream и OutputStream предназначены для байтовых потоков, а Reader и Writer - для символьных. Классы байтовых потоков и классы символьных потоков формируют отдельные иерархии. В необходимо использовать классы символьных потоков, имея дело с символами строк, а классы байтовых потоков - работая с байтами или другими двоичными объектами.
    10.5.1 Байтовые потоки

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

    InputStream - абстрактный класс, определяющий jаvа-модель байтового потокового ввода. Он реализует интерфейс C1oseable. Большинство методов этого класса в случае возникновения ошибочных ситуаций возбуждает исключение IOException.

    OutputStream - абстрактный класс, определяющий потоковый байтовый вывод. Реализует интерфейсы Closeable и Flushable. Большинство методов этого класса возвращают void и возбуждают IOException в случае ошибок.

    Класс FileInputStream создает InputStream, который вы можете использовать для чтения байт из файла. Так выглядят два его наиболее часто используемые конструктора:

    FileInputStream(String filepath)

    FileInputStream(File fileObj)

    Каждый из них может возбудить исключение FileNotFoundException. Здесь filepath - полное путевое имя файла, а fileObj - объект File, описывающий файл.

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

    FileInputStream f0 = new FileInputStream (" / autoexec. bat")

    File f = new File("/autoexec.bat");

    FileInputStream fl = new FileInputStream(f);

    Хотя первый конструктор, вероятно, используется чаще, второй позволяет внимательно исследовать файл с помощью методов класса File, прежде чем при соединять его к входному потоку. При создании Fi1eInputStream он также открывается для чтения. FileInputStream переопределяет шесть своих методов абстрактноrо класса InputStream. Методы mark () и reset () не переопределяются, и все попытки использовать reset() с Fi1eInputStream приводят к возникновению IOException.

    Следующий пример показывает, как прочесть один байт, массив байтов и поддиапазон массива байт. Также он иллюстрирует, как использовать available() для определения оставшегося числа байт, а также метод skip() - для пропуска нежелательных байт. Программа читает свой собственный исходный файл, который должен присутствовать в текущем каталоге.

    // Demonstrate FileInputStream.

    import java.io.*;

    class FileInputStreamDemo {

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

    int size;

    InputStream f = new FileInputStream("Fi1eInputStreamDemo.java");

    System.out.println("Total Available Bytes: "+ (size = f.available());

    int n = size/40;

    System.out.println("First "+ n +" bytes of the fi1e one read() at а time");

    for (int I = 0; i < n; i++) {

    System.out.print((char) f.read());

    }

    System.out.println("\nSti11 Available: " + f.available());

    System.out.println("Reading the next " + n + " with one read(b[])");

    byte b [] = new byte [n] ;

    if (f.read(b) != n) {

    System.err.println("couldn't read " + n + " bytes.");

    }

    System.out.println(new String(b, 0, n));

    System.out.println("\nStill Available: "+ (size = f.available());

    System.out.println("Skipping half of remaining bytes with skip()");

    f.skip(size/2);

    System.out.println("Still Available: " + f.available();

    System.out.println("Reading" + n/2 + " into the end of array");

    if (f.read(b, n/2, n/2) != n/2) {

    System.err.println("couldn't read " + n/2 + " bytes.");

    }

    System.out.println(new String(b, 0, b.length));

    System.out.println("\nStill Available: " + f.available();

    f.close();

    Так выглядит вывод этой программы:

    Total Available Bytes: 1433

    First 35 bytes of the file one read() at а time

    // Demonstrate FileInputStream.

    im

    Still Available: 1398

    Reading the next 35 with one read(b[])

    port java.io.*;

    c1ass FileInputS

    Still Available: 1363

    Skipping half of remaining bytes with skip()

    Still Available: 682

    Reading 17 into the end of array

    port java.io.*;

    read(b) != n) {

    S

    Still Available: 665

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

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

    FileOutputStream(String filePath)

    FileOutputStream(File fileObj)

    FileOutputStream(String filePath, boolean append)

    FileOutputStream (File fileObj, boolean append)

    Они могут возбуждать исключение FileNotFoundException. Здесь filePath - полное путевое имя файла, а fileObj - объект File, описывающий файл. Если параметр append равен true, файл открывается в режиме добавления.

    Создание Fi1eOutputStream не зависит от того, существует ли указанный файл.

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

    В следующем примере создается буфер байт, сначала создавая String, а затем используя метод getBytes() для извлечения ее эквивалента в виде байтовorо массива. Затем создаются три файла. Первый – file1.txt, будет содержать каждый второй байт примера. Второй - file2.txt, будет содержать полный набор байт. Третий и последний – filе3.txt, будет содержать только последнюю четверть.

    // Демонстрация применения FileOutputStream.

    import java.io.*;

    class FileOutputStreamDemo {

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

    String source = "Now is the time for all good mеn\n"

    + " to соmе to the aid of their country\n"

    + " and рау their due taxes.";

    byte buf[] = source.getBytes();

    OutputStream f0 = new FileOutputStream("file1.txt");

    for (int i = 0; i < buf.length; i += 2) {

    f0.write(buf[i]);

    }

    f0.close() ;

    OutputStream f1 = new FileOutputStream("file2.txt");

    f1.write (buf);

    f1.close () ;

    OutputStream f2 = new FileOutputStream("file3.txt");

    f2.write(buf,buf.1ength-buf.length/4,buf.length/4);

    f2.close () ;

    }

    }

    Так будет выглядеть содержимое каждого файла после выполнения этой программы.

    Сначала file1. txt:

    Nwi h iefralgo е

    t oet h i ftercuty n а hi u ае.

    Затем file2 . txt:

    Now is the time for all good men

    to соmе to the aid of their country

    and рау their due taxes.

    И, наконец, fi1е3. txt:

    nd рау their due taxes.

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

    ByteArrayInputStream(byte array[ ])

    ByteArrayInputStream (byte array[ ], int start/' int nuтBytes)

    Здесь array - источник данных. Второй конструктор создает InputStream из подмножества вашего байтового массива, который начинается с символа в позиции, указанной в start, и длиной, равной numBytes.

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

    ByteArrayOutputStream( )

    ByteArrayOutputStream(int numBytes)

    В первой форме создается буфер в 32 байта размером. Во втором создается буфер указанноrо в параметре numBytes размера. Буфер хранится в защищенном поле buf класса ByteArrayOutputStream. Размер буфера увеличивается автоматически по мере необходимости. Количество байт, содержащееся в буфере, хранится в защищенном поле count класса ByteArrayOutputStream.

    Буферизация ввода-вывода - очень распространенный способ оптимизации производительности. Класс BufferedInputStream позволяет поместить в оболочку любой поток InputStream и достичь увеличения производительности.

    BufferedInputStream имеет два конструктора:

    BufferedInputStream(InputStream inputStreaт)

    BufferedInputStream(InputStream inputStreaт, int bufSize)

    Первая форма создает буферизованный поток, использующий размер буфера по умолчанию. Во втором размер буфера указывается в bufSize. Рекомендуется использовать размеры буфера, кратные размеру страницы памяти, дисковому блоку и тому подобному - это окажет существенное положительное влияние на производительность. С другой стороны, однако, это зависит от реализации. Необязательный размер буфера обычно зависит от принимающей операционной системы, объема доступной памяти и конфигурации машины. Чтобы добиться эффективного использования буферизации, не обязательно погружаться во все эти сложности. Хорошим предположением будет установить размер буфера для потока ввода-вывода в 8192 байта или даже меньше. Таким образом, низкоуровневая система сможет читать блоки данных с диска или из сети и сохранять результат в вашем буфере. То есть, даже если вы читаете данные по одному байту из InputStream, то большую часть времени будете иметь дело с быстрой памятью.

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

    В отличие от буферизованного ввода буферизованный вывод не предоставляет дополнительной функциональности. Буферы вывода в java нужны для повышения производительности. Вот два доступных конструктора этоrо класса:

    BufferedOutputStream(OutputStream outputStreaт)

    BufferedOutputStream(OutputStream outputStreaт, int bufSize)

    Первая форма создает буферизованный поток, используя размер буфера по умолчанию. Во второй форме размер буфера передается в bufSize.

    Класс SequenceInputStream позволяет соединять вместе несколько экземпляров InputStream. Конструирование SequenceInputStream отличается от любого другого InputStream. Конструктор SequenceInputStream принимает в качестве аргумента либо пару InputStream, либо Enumeration из InputStream.

    Класс PrintStream предоставляет все возможности вывода, которыми мы пользуемся с дескриптором файла System - System.out. Это делает PrintStream одним из наиболее часто используемых классов jаvа. Он реализует интерфейсы Appendable, Closeable и Flushable.

    PrintStream определяет несколько конструкторов.

    PrintStream(OutpиtStream outputStreaт)

    PrintStream(OutputStream outputStreaт, boolean flushOnNewline)

    PrintStream(OutputStream outputStream, boolean flushOnNewline, String charSet)

    Здесь outputStream указывает открытый OutputStrеаm, который будет принимать вывод. Параметр flushOnNewline управляет тем, будет ли выходной буфер автоматически сбрасываться при каждой записи символа новой строки (\n), записи байтового массива либо вызове println (). Если flushOnNewline равен true, происходит автоматический сброс. Если же он равен false, сброс будет неавтоматическим. Первый конструктор не включает автоматический сброс. Вы можете специфицировать кодировку символов, передав ее имя в charSet.

    DataOutputStream и DataInputStream позволяют писать или читать примитивные данные в поток и из него. Они реализуют интерфейсы DataOutput и DataInput соответственно. Эти интерфейсы определяют методы, преобразующие примитивные значения в форму последовательности байт. Такие потоки облегчают сохранение в файле двоичных данных, таких как целочисленные значения или значения с плавающей точкой.

    DataOutputStream расширяет FilerOutputStream, который, в свою очередь, расширяет OutputStream.

    В DataOutputStream определен следующий конструктор:

    DataOutputStream(OutputStream outputStream)

    Здесь outputStream специфицирует выходной поток, в который будут записаны данные.

    DataOutputStream поддерживает все методы, определенные его суперклассами.

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

    Вот образцы этих методов:

    final void writeDouble(double value) throws IOException

    final void writeBoolean(boolean value) throws IOException

    final void writelnt(int value) throws IOException

    Здесь value - значение, записываемое в поток.

    DataInputStream - это дополнение DataOutputStream. Он расширяет FilterInputStream, который в свою очередь, расширяет InputStream. DatalnputStream определяет только один следующий конструктор:

    DataInputStream(InputStream iпputStream)

    Здесь inputStream специфицирует входной поток, откуда будут читаться данные. Как и DataOutputStream, DatalnputStream поддерживает все методы своих суперклассов, наряду с методами, определенными интерфейсом DataInput, что и делает его уникальным. Эти методы читают последовательность байтов и преобразуют их в значения примитивных типов. Ниже показаны образцы этих методов:

    double readDouble( ) throws IOException

    boolean readBoolean( ) throws IOException

    int readlnt( ) throws IOException
    10.5.2 Символьные потоки

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

    Reader - абстрактный класс, определяющий символьного потокового ввода jаvа. Он реализует интерфейсы Closeable и Readable. Все методы этого класса (за исключением markSupported () ) в случае ошибочных ситуаций возбуждают исключение IOException.

    Writer - абстрактный класс, определяющий символьный потоковый вывод. Реализует интерфейсы Closeable, Flushable и Appendable. Все методы этого класса в ошибочных ситуациях возбуждают исключение IOException.
    10.6 Использование потокового вода-вывода

    Экземпляр StreamTokenizer создается поверх существующего объекта, либо InputStream, либо Reader. Как и java.util.StringTokenizer, этот класс позволяет разбивать данные на лексемы (token), выделяемые из потока по определенным свойствам. Поскольку работа ведется со словами, конструктор, принимающий InputStream, объявлен как deprecated (предлагается оборачивать байтовый поток классом InputStreamReader и вызывать второй конструктор). Общий принцип работы такой же, как и у StringTokenizer, – задаются параметры разбиения, после чего вызывается метод nextToken(), пока не будет достигнут конец потока. Способы задания разбиения у StreamTokenizer довольно разнообразны, но просты, и поэтому здесь не рассматриваются.

    10.7 Сериализация

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

    Поскольку сериализованный объект – это последовательность байт, которую можно легко сохранить в файл, передать по сети и т.д., то и объект затем можно восстановить на любой машине, вне зависимости от того, где проводилась сериализация. Разумеется, Java позволяет не задумываться при этом о таких факторах, как, например, используемая операционная система на машине-отправителе и получателе. Такая гибкость обусловила широкое применение сериализации при создании распределенных приложений, в том числе и корпоративных (enterprise) систем.

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

    Переменные, объявленные как transient, не сохраняются средствами сериализации.

    Также не сохраняются переменные static.

    Средства java для сериализации и десериализации спроектированы так, что большая часть работы по сохранению и восстановлению состояния объекта выполняется автоматически. Однако бывают случаи, когда программисту нужно управлять этим процессом. Например, может оказаться желательным использовать технологии сжатия и шифрования. Интерфейс Externa1izable предназначен именно для таких ситуаций.

    Интерфейс Externa1izable определяет следующие два метода:

    void readExternal(ObjectInput inStream)

    throws IOException, ClassNotFoundException

    void writeExternal(ObjectOutput outStreaт)

    throws IOException

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

    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. Реализовать многопоточное приложение, реализующее поиск подстроки в файлах. Список файлов передается в качестве параметра командной строки. Для каждого файла выделяется отдельный поток.
    Контрольные вопросы

    1. Для чего предназначен пакет java.io?

    2. Какие существуют классы ввода-вывода?

    3. С чем имеет дело класс File?

    4. Какие конструкторы используются для создания объектов типа File?

    5. Что такое каталог?

    6. Для чего используется метод list()?

    7. С помощью каких методов можно создать каталог?

    8. Для чего служат байтовые потоки?

    9. Какие существуют классы байтовых потоков?

    10. Для чего служат символьные потоки?

    11. Какие существуют классы символьных потоков?


    Рекомендуемая литература

    1. Г. Шилдт Полный справочник по Java. – М., Киев: «Вильямс», 2007

    2. Б. Эккель Философия Java. – М., Киев: «Питер», 2009

    3. К. С. Хорстманн Основы Java. – М.: «Вильямс», 2003

    4. А. А. Кубенский Создание и обработка структур данных в примерах на Java. – СПб.: «БХВ – Петербург», 2001

    5. Д. Флэнаган Java в примерах. Справочник. – СПб: «Символ – Плюс», 2003
    1   ...   23   24   25   26   27   28   29   30   31


    написать администратору сайта