Ответы на вопросы по ревью 4. Java io. Ключевым понятием здесь является понятие потока
Скачать 1.93 Mb.
|
|
1 | public static Object clone(Serializable object); |
Он в основном выполняет глубокое клонирование с использованием сериализации. Это полезно, поскольку глубокое клонирование с использованием метода клонирования объекта очень болезненно и подвержено ошибкам для сложных графов объектов.
Минусы:
Это во много раз медленнее, чем ручное клонирование всех объектов в вашем экземпляре объекта.
Если используется этот метод, все задействованные объекты должны быть Serializable, т. е. объекты должны реализовывать Сериализуемый интерфейс; в противном случае он выкинет java.io.NotSerializableException.
Следующая программа демонстрирует это:
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | import org.apache.commons.lang3.SerializationUtils; import java.io.Serializable; import java.util.*; // `Subject` также должен реализовать интерфейс `Serializable`!! class Subject implements Serializable { private Set public Subject() { subjects = new HashSet<>( Arrays.asList("Maths", "Science", "English", "History") ); } @Override public String toString() { return subjects.toString(); } public Set return subjects; } } // Обратите внимание, что `Student` реализует интерфейс `Serializable` class Student implements Serializable { private String name; // неизменяемое поле private int age; // примитивное поле private Subject subjects; private Map public Student(String name, int age) { this.name = name; this.age = age; map = new HashMap put(name, age); }}; subjects = new Subject(); } @Override public String toString() { return Arrays.asList(name, String.valueOf(age), subjects.toString()).toString(); } public Set public Map // включаем оставшиеся геттеры и сеттеры } // Демонстрация глубокого копирования объектов с помощью метода `clone()`, предоставляемого // `SerializationUtils` Apache Common class Main { // Вспомогательный метод для сравнения двух объектов. Он печатает мелкую копию // если оба объекта имеют один и тот же объект; в противном случае он печатает глубокую копию public static void compare(Object ob1, Object ob2) { if (ob1 == ob2) { System.out.println("Shallow Copy"); } else { System.out.println("Deep Copy"); } }; public static void main(String[] args) { Student student = new Student("Jon Snow", 22); // вызов метода `clone()` SerializationUtils Student clone = (Student) SerializationUtils.clone(student); System.out.println("Cloned Object: " + clone.toString() + '\n'); compare(student.getSubjects(), clone.getSubjects()); compare(student.getMap(), clone.getMap()); // любые изменения, внесенные в карту клона, не отразятся на карте ученика clone.getMap().put("John Cena", 40); System.out.println(student.getMap()); } } |
Скачать код
результат:
Cloned Object: [Jon Snow, 22, [Jon Snow, 22]]
Deep Copy
Deep Copy
{Jon Snow=22}
Это все о clone() метод в Java.
Что такое InputStream и OutputStream?
Абстрактные классы InputStream и OutputStream нужны для того, чтобы абстрагировать различные способы ввода и вывода, независимо от того, является ли поток файлом, веб- страницей или картинкой.
InputStream используется для считывания информации. OutputStream используется для записи информации.
Почему важно закрывать потоки?
При закрытии потока освобождаются все выделенные для него ресурсы, например, файл. В случае, если поток окажется не закрыт, может произойти утечка памяти.
Какие потоки можно не закрывать (не вызывать метод close())?
В JDK 7 метод close() определяется интерфейсом AutoCloseable и можно явно не закрывать поток, а использовать оператор try-with-resources, в котором в неявно созданном finally будет вызываться метод close().
Что делает метод available()?
Метод available() проверяет, есть ли данные в файле и возвращает примерное количество доступных для чтения байтов.
Можно ли использовать flush() для небуферизированного потока и что будет?
Метод flush() для небуферезированного потока использовать можно, т.к исходя из документации, "среда хоста может выполнять свою собственную буферизацию, неизвестную Java. В этом случае запись можешь кэшироваться в буферах ОС".
На каком паттерне основана иерархия потоков ввода/вывода?
Объекты классов Java, которые используются для ввода/вывода, для обеспечения необходимой функциональности наслаиваются друг на друга.
Такая модель взаимодействия объектов возможна в паттерне "Декоратор". В этом паттерне, при создании потока, нужно использовать несколько объектов.
Что делает метод read. Почему он возвращает int а не byte. Почему он не может возвращать byte?
Метод read() используется для чтения символов.
Данный метод возвращает кол-во только что прочитанных символов (целое число от 0 до 65635) или -1, если достиг конца stream(потока).
Он возвращает int, потому что диапазон byte в Java лежит от -127 до 127, а возвращаемое значение метода read() лежит в диапазоне от 0 до 255.
Чтобы получит представление byte в int, в методе read() используется побитовое "И" с числом 255, т.е убираются лидирующие единицы.
Что вернет метод read(), если он считывает файл и ему встречается байт равный -1?
Если методу read() встречается байт равный -1, то он вернет значение, к которому применилось побитовое "И" с числом 255. Т.е вернёт 255.
Для чего нужен Scanner?
Сканер нужен для считывания данных из источника, который мы для него указываем. Например, из строки, файла или консоли. Далее он распознает эту информацию и обрабатывает нужным образом.
Сканер выполняет поиск токенов во входной строке.
Что такое токен в Scanner?
Токен — это серия цифровых или буквенно-цифровых символов, которые заканчиваются разделителем.
Отличие Scanner'a от BufferedReader'a
BufferedReader имеет значительно большую буферную память (8192 символа), чем . Используйте BufferedReader, если необходимо просто получить длинные строки из потока, и используйте , если хотите разобрать определенный тип токенов из потока.
BufferedReader является синхронным, а — нет. Используйте , если хотите работать с несколькими потоками.
Scanner скрывает IOException, в то время как бросает его немедленно.
Есть ли у сканера буфер?
У сканера есть буфер, но он довольно маленький — всего 1024 символа.
Абсолютный и относительный путь
Абсолютный путь всегда содержит корневой элемент и полный список каталогов, для нахождения файла.
Например: "c:\\windows\\projects\\note.txt" — это абсолютный путь. Для проверки, является ли путь абсолютным, есть метод isAbsolute().
Относительный путь необходимо соединить с другим путем, чтобы получить доступ к файлу. Например, joe/foo — это относительный путь.
Без дополнительной информации, программа не сможет достоверно определить местоположение каталога joe/foo в файловой системе.
Методы класса File
createNewFile() - создает новый файл по пути, который передан в конструкторе;
delete() - удаляет каталог или файл по пути, который передан в конструкторе;
exists() - проверяет, существует ли по указанному в конструкторе пути файл или каталог; getAbsolutePath() - возвращает абсолютный путь для пути, который передан в конструктор getName() - возвращает краткое имя файла или каталога
length() - возвращает размер файла в байтах
mkdir() - создает новый каталог и при удачном создании возвращает значение true
Как создать файл на компьютере с помощью Java?
Для создания нового файла, во время инициализации объекта File, мы должны предоставить ему имя файла, а затем создать сам новый файл вызовом метода createNewFile().
Создать файл в Java с помощью объекта File можно тремя способами: 1. Передав в объект абсолютный путь
2. Указать только имя файла
3. Указать относительный путь
Как удалить директорию с файлами. Что если в ней есть вложенные директории?
Чтобы удалить директорию с файлами, сначала необходимо удалить сами файлы в папке, а затем и саму папку.
В чём отличие File от Path
File - класс, самая старая версия работы с папками и файлами
Его методы возвращают тру/фолс
Path - интерфейс, гораздо новый, его методы выбрасывают исключение в случае проблем
Что такое клонирование. Как реализовано клонирование в Java?
Иногда нужно на основе существующего объекта создать второй такой же, то есть - создать его клон. Этот процесс в Java называется клонированием.
Клонировать объект в Java можно тремя способами:
1. Переопределение метода clone() и реализация интерфейса Cloneable; 2. Использование конструктора копирования;
3. Использовать для клонирования механизм сериализации;
Клонирование объекта. Глубокое и поверхностное.
Поверхностное копирование
копирует настолько маленькую часть, насколько это возможно. По умолчанию, копирование в Java является поверхностным, т.е Object class не знает о структуре
класса, которого он копирует.
Глубокое копирование дублирует всё. Глубокое копирование — это две коллекции, в одну из которых дублируются все элементы оригинальной коллекции. Мы хотим сделать копию, при которой внесение любых изменений в копию не затронет оригинальную коллекцию.
Чем отличается копирование от клонирования?
При копировании объектов, мы создаем не новый объект, а объект, который ссылается на копируемый. Т.е изменения, которые мы произведем во втором объекте, будут так же отражены и в первом.
При клонировании, мы создаем отдельную копию первого объекта, но со своей собственной ссылкой. При этом каждый объект будет иметь свою собственную ссылку.
Можно ли клонировать String, массив String?
Класс String представляет неизменяемую строку. Нет смысла клонировать String. Если вы чувствуете, что вам нужно клонировать его, вы можете просто повторно использовать ту же ссылку и добиться того же эффекта.
Даже если бы вы могли clone s1 как s2, тогда s1 != s2 все равно был бы true. Они по-прежнему будут ссылками на отдельные объекты.
Массив String клонировать можно, т.к он реализует интерфейс Cloneable
Что такое сериализация и десериализация?
Сериализация — процесс сохранения состояния объекта в последовательность байт. Десериализация — процесс восстановления объекта из этих байт.
Любой Java объект можно преобразовать в последовательность байт.
Одно уточнение — чтобы появилась возможность сериализовать объект, он должен наследовать интерфейс Serializable.
Данный интерфейс не имеет каких-либо методов, а просто дает понять системе, что объект, который реализует его, может быть сериализован.
Для сериализации объектов в поток используется класс ObjectOutputStream. Он записывает данные в поток.
Для десериализации используется класс ObjetInputStream
Назовите несколько форматов сериализации
Основные форматы сериализации:
JSON YAML XML BSON
Как сериализовать объект класса?
Чтобы сериализовать объект класса, мы сначала создаем файл, в который будем записывать объект, затем преобразуем объект в байты и с помощью метода writeObject() сохраняем.
Что делать, если одно из полей сериализовывать не нужно?
Чтобы сериализовать определенные поля, можно воспользоваться одним из двух методов:
1. Использовать ключевое слово transient
2. Вместо реализации Seriazable использовать его расширение — интерфейс Externalizable
При использовании слова transient мы явно указываем, какое поле или поля не нужно сериализовывать.
При использовании интерфейса Externalizable нам необходимо переопределить два метода writeExternal() и readExternal(). В методе writeExternal() мы указываем, какие поля будут сериализованы, а в readExternal() как прочитать эти поля.
Как сериализовать статическое поле?
При стандартной сериализации, поля с модификатором static не сериализуются. Соответственно, после десериализации это поле значение не поменяет.
При использовании реализации Externalizable сериализовать и десериализовать статическое поле можно, но не рекомендуется этого делать, т.к. это может сопровождаться трудноуловимыми ошибками.
Externalizable vs Serializable
При записи Serializable класса весь контроль над сериализацией достается JVM.
Интерфейс Externalizable расширяет Serializable и добавляет методы записи и чтения writeExternal и readExternal. Этот интерфейс позволяет реализовать полностью свой механизм сериализации, стандартно запишется только идентификатор класса.
Что если при десериализации поменять тип?
Если при десериализации поменять тип поля, то можно получить исключение ClassCastException.
Например, если при десериализации я захочу изменить тип данных со строки на список, то получу исключение, потому что он не может преобразовать строку в список.
Что будет при сериализации объекта у которого есть поле и оно не Serializable?
Если это поле находится в классе, от которого наследуется класс, над которым будет проходить сериализация, то это поле должно быть доступно напрямую или через геттеры и сеттеры классу, над которым будет проходить сериализация. В этом классе придется реализовать пользовательскую сериализацию.
Ещё один из приемлемых вариантов — это пометить поле transient, чтобы оно игнорировалось во время процессов сериализации и десериализации.
Особенность сериализации поля final
Поля с модификатором final сереализуются, как обычные. За одним исключением — их невозможно десериализовать при использовании Externalizable.
Отличие пакетов IO и NIO, InputStream от Reader.
Основное отличие IO от NIO в том, что IO , а NIO буферо-ориентированным
Потокоориентированный ввод/вывод подразумевает чтение/запись из потока/в поток одного или нескольких байт в единицу времени поочередно.
Подход, на котором основан Java NIO немного отличается. Данные считываются в буфер для последующей обработки.
Блокирующий и неблокирующий ввод/вывод
Потоки ввода/вывода (streams) в Java IO являются блокирующими.
Это значит, что когда в потоке выполнения (tread) вызывается read() или write() метод любого класса из пакета java.io.*, происходит блокировка до тех пор, пока данные не будут считаны или записаны. Поток выполнения в данный момент не может делать ничего другого.
Неблокирующий режим Java NIO позволяет запрашивать считанные данные из канала (channel) и получать только то, что доступно на данный момент, или вообще ничего, если доступных данных пока нет. Вместо того, чтобы оставаться заблокированным пока данные не станут доступными для считывания, поток выполнения может заняться чем-то другим.
InputStream и Reader
InputStream - это сырой метод получения информации из ресурса. Он захватывает данные байт за байтом, не выполняя никакого перевода. Если вы читаете данные изображения или любой двоичный файл, этот поток следует использовать.
Reader предназначен для потоков символов. Если информация, которую вы читаете, полностью состоит из текста, то Reader позаботится о декодировании символов и предоставит символы юникода из необработанного входного потока.
Что такое System.in, что такое System.out?
System.in — это "стандартный" поток ввода и объект InputStream. Этот поток уже открыт и готов к подаче входных данных. Обычно этот поток соответствует вводу с клавиатуры или другому источнику ввода, заданному окружением хоста или пользователем.
System.out — это "стандартный" поток вывода и объект PrintStream. Этот поток уже открыт и готов к приему выходных данных. Обычно этот поток соответствует выводу на дисплей или другому месту вывода, указанному окружением хоста или пользователем.
Что такое потоки ввода и вывода. Как это реализовано в Java?
Разделяют 2 вида потоков байтовые и системные.
Байтовые: java.io.InputStream,java.io.OutputStream;
Символьные: java.io.Reader, java.io.Writer;
Какие интерфейсы реализует InputStream/ OutputStream/ Reader/ Writer?
InputStream реализует интерфейсы: Closeable и AutoCloseable
OutputStream реализует интерфейсы: Closeable, Flushable, AutoCloseable
Reader реализует интерфейсы: Closeable, AutoCloseable, Readable
Writer реализует интерфейсы: Closeable, Flushable, Appendable, AutoCloseable
Что такое паттерн адаптер и паттерн декоратор
Паттерн проектирования адаптер — это такой шаблон проектирования, который позволяет обернуть несовместимые объекты в адаптер, чтобы сделать их совместимыми друг с другом.
Паттерн проектирования декоратор — шаблон декоратор позволяет вам динамически изменять поведение объекта во время работы, оборачивая их в объект класса декоратора.
Представим, что у вас есть свой автосервис. Как вы будете рассчитывать сумму в счете за услуги? Вы выбираете одну услугу и динамически добавляете к ней цены на предоставляемые услуги, пока не получите окончательную стоимость. Здесь каждый тип сервиса является декоратором.
что делает flush? выполнится ли flush если мы сделаем close?
Flush очищает буфер и скидывает содержимое в поток
Да, выполнится
В соответствии с документами java, вызывая close() на любом потоке java.io, автоматически вызывает flush(). Но я видел много примеров, даже в производственных кодексах разработчики явно использовали flush() непосредственно перед close()
Разница между mkdir и mkdirs
javadocs для mkdirs() :
Создает каталог с именем этого абстрактного пути, включая все необходимые, но несуществующие родительские каталоги. Обратите внимание, что в случае сбоя этой операции, возможно, удалось создать некоторые из необходимых родительских каталогов.
javadocs для mkdir() :
Создает каталог с именем этого абстрактного пути.
Вопросы
1. Какие существуют виды потоков ввода/вывода?
2. Назовите основные предки потоков ввода/вывода.
3. Что общего и чем отличаются следующие потоки: InputStream, OutputStream, Reader, Writer?
4. Что вы знаете о RandomAccessFile?
5. Какие есть режимы доступа к файлу?
6. В каких пакетах лежат классы-потоки?
7. Что вы знаете о классах-надстройках?
8. Какой класс-надстройка позволяет читать данные из входного байтового потока в формате примитивных типов данных?
9. Какой класс-надстройка позволяет ускорить чтение/запись за счет использования буфера?
10. Какие классы позволяют преобразовать байтовые потоки в символьные и обратно?
11. Какой класс предназначен для работы с элементами файловой системы (ЭФС)?
12. Какой символ является разделителем при указании пути к ЭФС?
13. Как выбрать все ЭФС определенного каталога по критерию (например, с определенным расширением)?
14. Что вы знаете об интерфейсе FilenameFilter?
15. Что такое сериализация?
16. Какие условия “благополучной” сериализации объекта?
17. Какие классы позволяют архивировать объекты?
Ответы
1. Какие существуют виды потоков ввода/вывода?
Разделяют два вида потоков ввода/вывода: байтовые и символьные.
Система ввода/вывода: http://developer.alexanderklimov.ru/android/java/io.php
Oracle Lesson: Basic I/O tutorial: https://docs.oracle.com/javase/tutorial/essential/io/
2. Назовите основные предки потоков ввода/вывода.
Байтовые: java.io.InputStream, java.io.OutputStream;
Символьные: java.io.Reader, java.io.Writer;
3. Что общего и чем отличаются следующие потоки: InputStream, OutputStream, Reader, Writer?
Базовый класс InputStream представляет классы, которые получают данные из различных источников:
— массив байтов
— строка (String)
— файл
— канал (pipe): данные помещаются с одного конца и извлекаются с другого
— последовательность различных потоков, которые можно объединить в одном потоке
— другие источники (например, подключение к интернету)
Класс OutputStream — это абстрактный класс, определяющий потоковый байтовый вывод. В этой категории находятся классы, определяющие, куда направляются ваши данные: в массив байтов (но не напрямую в String; предполагается что вы сможете создать их из массива байтов), в файл или канал.
Символьные потоки имеют два основных абстрактных класса Reader и Writer, управляющие потоками символов Unicode. Класс Reader — абстрактный класс, определяющий символьный потоковый ввод. Класс Writer — абстрактный класс, определяющий символьный потоковый вывод. В случае ошибок все методы класса передают исключение IOException.
4. Что вы знаете о RandomAccessFile?
Класс RandomAccessFile наследуется напрямую от Object и не наследуется от вышеприведенных базовых классов ввода\вывода. Предназначен для работы с файлами, поддерживая произвольный доступ к их содержимому.
Работа с классом RandomAccessFile напоминает использование совмещенных в одном классе потоков DataInputStream'>DataInputStream и DataOutputStream (они реализуют те же интерфейсы DataInput и DataOutput). Кроме того, метод seek() позволяет переместиться к определенной позиции и изменить хранящееся там значение.
При использовании RandomAccessFile необходимо знать структуру файла. Класс RandomAccessFile содержит методы для чтения и записи примитивов и строк UTF-8.
5. Какие есть режимы доступа к файлу?
RandomAccessFile может открываться в режиме чтения («r») или чтения/записи («rw»). Также есть режим «rws», когда файл открывается для операций чтения-записи и каждое изменение данных файла немедленно записывается на физическое устройство.
6. В каких пакетах лежат классы-потоки?
Классы потоков ввода\вывода лежат в java.io; С JDK 7 добавлен более современный способ работы с потоками — Java NIO. Классы лежат в java.nio. Для работы с архивами используются классы из пакета java.util.
7. Что вы знаете о классах-надстройках?
Классы-надстройки наделяют существующий поток дополнительными свойствами. Примеры классов: BufferedOutputStream, BufferedInputStream, BufferedWriter — буферизируют поток и повышают производительность.
8. Какой класс-надстройка позволяет читать данные из входного байтового потока в формате примитивных типов данных?
Для чтения байтовых данных (не строк) применяется класс DataInputStream. В этом случае необходимо использовать классы из группы InputStream.
Для преобразования строки в массив байтов, пригодный для помещения в поток ByteArrayInputStream, в классе String предусмотрен метод getBytes(). Полученный ByteArrayInputStream представляет собой поток InputStream, подходящий для передачи DataInputStream.
При побайтовом чтении символов из форматированного потока DataInputStream методом readByte() любое полученное значение будет считаться действительным, поэтому возвращаемое значение неприменимо для идентификации конца потока. Вместо этого можно использовать метод available(), который сообщает, сколько еще осталось символов.
Класс DataInputStream позволяет читать элементарные данные из потока через интерфейс DataInput, который определяет методы, преобразующие элементарные значения в форму последовательности байтов. Такие потоки облегчают сохранение в файле двоичных данных.
Конструктор: DataInputStream(InputStream stream)
Методы: readDouble(), readBoolean(), readInt()
9. Какой класс-надстройка позволяет ускорить чтение/запись за счет использования буфера?
Для этого используются классы, позволяющие буферизировать поток:
java.io.BufferedInputStream(InputStream in) || BufferedInputStream(InputStream in, int size),
java.io.BufferedOutputStream(OutputStream out) || BufferedOutputStream(OutputStream out, int size),
java.io.BufferedReader(Reader r) || BufferedReader(Reader in, int sz),
java.io.BufferedWriter(Writer out) || BufferedWriter(Writer out, int sz)
10. Какие классы позволяют преобразовать байтовые потоки в символьные и обратно?
OutputStreamWriter — мост между классом OutputStream и классом Writer. Символы, записанные в поток, преобразовываются в байты.
1 2 3 4 5 6 | OutputStream outputStream = new FileOutputStream("c:\\data\\output.txt"); Writer outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8"); outputStreamWriter.write("Hello World"); outputStreamWriter.close(); |
InputStreamReader — аналог для чтения. При помощи методов класса Reader читаются байты из потока InputStream и далее преобразуются в символы.
1 2 3 4 5 6 7 8 9 10 | InputStream inputStream = new FileInputStream("c:\\data\\input.txt"); Reader inputStreamReader = new InputStreamReader(inputStream, "UTF-8"); int data = inputStreamReader.read(); while(data != -1){ char theChar = (char) data; data = inputStreamReader.read(); } inputStreamReader.close(); |
11. Какой класс предназначен для работы с элементами файловой системы (ЭФС)?
В отличие от большинства классов ввода/вывода, класс File работает не с потоками, а непосредственно с файлами. Данный класс позволяет получить информацию о файле: права доступа, время и дата создания, путь к каталогу. А также осуществлять навигацию по иерархиям подкаталогов. Класс java.io.File может представлять имя определённого файла, а также имена группы файлов, находящихся в каталоге. Если класс представляет каталог, то его метод list() возвращает массив строк с именами всех файлов.
Для создания объектов класса File можно использовать один из следующих конструкторов:
File(File dir, String name) — указывается объект класса File (каталог) и имя файла
File(String path) — указывается путь к файлу без указания имени файла
File(String dirPath, String name) — указывается путь к файлу и имя файла
File(URI uri) — указывается объекта URI, описывающий файл
12. Какой символ является разделителем при указании пути к ЭФС?
Для различных систем символ разделителя различается. Вытащить его можно используя file.separator, а так же в статическом поле File.separator. Для Windows это ‘\’.
*На stackoverflow встречал утверждение со ссылкой на документацию, что можно безопасно использовать слэш ‘/’ для всех систем. В комментарии читатель подтвердил это.
13. Как выбрать все ЭФС определенного каталога по критерию (например, с определенным расширением)?
Метод File.listFiles() возвращает массив объектов File, содержащихся в каталоге. Метод может принимать в качестве параметра объект класса, реализующего FileFilter. Это позволяет включить список только те элементы, для которых метода accept возвращает true (критерием может быть длина имени файла или его расширение).
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 | public class FileDemo { public static void main(String[] args) { File f = null; File[] paths; try{ // create new file f = new File("c:/test"); // returns pathnames for files and directory paths = f.listFiles(); // for each pathname in pathname array for(File path:paths) { // prints file and directory paths System.out.println(path); } }catch(Exception e){ // if any error occurs e.printStackTrace(); } } } |
14. Что вы знаете об интерфейсе FilenameFilter?
Интерфейс FilenameFilter применяется для проверки попадает ли объект File под некоторое условие. Этот интерфейс содержит единственный метод boolean accept(File pathName). Этот метод необходимо переопределить и реализовать. Например:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public boolean accept(File file) { if (file.isDirectory()) { return true; } else { String path = file.getAbsolutePath().toLowerCase(); for (int i = 0, n = extensions.length; i < n; i++) { String extension = extensions[i]; if ((path.endsWith(extension) && (path.charAt(path.length() - extension.length() - 1)) == '.')) { return true; } } } return false; } //OR String yourPath = "insert here your path.."; File directory = new File(yourPath); String[] myFiles = directory.list(new FilenameFilter() { public boolean accept(File directory, String fileName) { return fileName.endsWith(".txt"); } }); |
15. Что такое сериализация?
Сериализация это процесс сохранения состояния объекта в последовательность байт; десериализация это процесс восстановления объекта, из этих байт. Java Serialization API предоставляет стандартный механизм для создания сериализуемых объектов.
Сериализация в Java: http://habrahabr.ru/post/60317/
Изучите секреты Java Serialization API: http://www.ccfit.nsu.ru/deviv/courses/oop/java_ser_rus.html
Как работает сериализация в Java (info.javarush.ru): http://goo.gl/K8GzJl
16. Какие условия “благополучной” сериализации объекта?
Чтобы обладать способностью к сериализации, класс должен реализовывать интерфейс-метку Serializable. Так же все атрибуты и подтипы сериализуемого класса должны быть сериализуемы. Если класс предок был несереализуемым, то этот суперкласс должен содержать доступный (public, protected) конструктор без параметров для инициализации полей.
17. Какие классы позволяют архивировать объекты?
DeflaterOutputStream, InflaterInputStream, ZipInputStream, ZipOutputStream, GZIPInputStream, GZIPOutputStream.
Пример из http://www.concretepage.com/java/how_to_zip_file_java.
Java
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 38 39 40 41 42 | package com.concretepage; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipOutputStreamTest { public static void main(String... args) throws IOException { String source="D:/page/file.txt"; File sfile= new File(source); String dest="D:/page/file.zip"; File dfile= new File(dest); FileInputStream fis= new FileInputStream(sfile); FileOutputStream fos= new FileOutputStream(dfile); ZipOutputStream zos= new ZipOutputStream(fos); ZipEntry ze= new ZipEntry(source); //begins writing a new zip file and sets the position to the start of data zos.putNextEntry(ze); byte[] buf = new byte[1024]; int len; while((len=fis.read(buf))>0){ zos.write(buf, 0, len); } System.out.println("File created:"+dest); fis.close(); zos.close(); } } |