Вы достигли нового уровня

Уровень 31

1. File, Files, Path

- Привет, Амиго. Давно не виделись.

- Привет, Билаабо. О чем будешь рассказывать?

- Сегодня я расскажу о работе с файлами. В Java есть специальный класс (File), с помощью которого можно управлять файлами на диске компьютера. Для того чтобы управлять содержимым файлов, есть другие классы: FileInputStream, FileOutputStream,…

- Интересно. А когда ты говоришь «управлять файлами», что ты имеешь в виду?

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

Можно сразу передавать имя файла в FileInputStream
FileInputStream input = new FileInputStream("c:/path/a.txt");
А можно отдельно создать объект-файл, а потом передать его в FileInputStream
File file = new File("c:/path/a.txt");
FileInputStream input = new FileInputStream(file);

- Но во втором случае длиннее же получается. Так и не понял – зачем эти файлы нужны.

- Для этого конкретного случая – да. Это не пример, как надо делать, а скорее – как можно.

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

Код
File folder = new File("c:/path/");
for (File file : folder.listFiles())
{
 System.out.println(file.getName());
}

- listFiles() – это метод, который возвращает список файлов в папке с именем «c:/path/»?

- Да. Хотя программисты обычно говорят «директория» или «каталог». Название «папка» стало употребляться совсем недавно, но, в принципе, они все верные, и ты можешь говорить, как тебе удобнее.

- Ок. А getName() что делает? Выдает имя файла? И какое именно имя? Полное вместе с путем или только имя самого файла?

- Только имя самого файла. Для полного есть file.getAbsolutePath()

- А какие еще методы есть у класса File?

- Вот, смотри:

МетодОписание
boolean isDirectory() Является ли «объект файла» директорией
boolean isFile() Является ли объект файлом
long length() Возвращает размер/длину файла в байтах.
boolean createNewFile() Создает файл. Если такой файл уже был, возвращает false.
boolean mkdir() Создает директорию. Название mkdir происходит от "make directory".
boolean mkdirs() Создает директорию и все поддиректории.
boolean delete() Удаляет файл объекта на диске. Если объект – директория, то только, если в ней нет файлов.
void deleteOnExit() Добавляет файл в специальный список файлов, которые будут автоматически удалены при закрытии программы.
File createTempFile(
 String prefix,
 String suffix,
 File directory)
Создает «временный файл» - файл с случайно сгенерированным уникальным именем – что-типа «dasd4d53sd».
Дополнительные параметры – префикс к имени, суффикс (окончание). Если директория не указана, то файл создается в специальной директории ОС для временных файлов
boolean exists() Возвращает true, если файл с таким именем существует на диске компьютера.
String getAbsolutePath() Возвращает полный путь файла со всеми поддиректориями.
String getCanonicalPath() Возвращает канонический путь файла.
Например, преобразовывает путь «c:/dir/dir2/../a.txt» к пути «c:/dir/a.txt»
String[] list() Возвращает массив имен файлов, которые содержатся в директории, которой является текущий объект-файл.
File[] listFiles() Возвращает массив файлов, которые содержатся в директории, которой является текущий объект-файл.
long getTotalSpace() Возвращает размер диска (количество байт) на котором расположен файл.
long getFreeSpace() Возвращает количество свободного места (количество байт) на диске, на котором расположен файл.
boolean renameTo(File) Переименовывает файл – содержимое файла фактически получает новое имя. Т.е. можно переименовать файл «c:/dir/a.txt» в «d:/out/text/b.doc».
String getName() Возвращает только имя файла, без пути.
String getParent() Возвращает только путь (директорию) к текущему файлу, без самого имени.
Path toPath() Возвращает объект Path, который соответствует текущему объекту File.

- Ничего себе! А не маленький такой список получился. Да и вроде, можно довольно много сделать с помощью него: создавать, удалять файлы, переименовывать,…

А чтобы получить директорию текущего файла, надо вызвать getParent()?

- Ага, но он вернет не объект-файл, а строку – путь к файлу. Фактически у класса File почти все методы дублированы: одна версия возвращает String, вторая File. Вот смотри:

 
File file = new File("c:/path/a.txt");
String directory = file.getParent();
File file = new File("c:/path/a.txt");
File directory = file.getParentFile();

Если у тебя есть строка с путем к файлу, а надо объект File, то воспользуйся конструктором. Если же наоборот – есть объект File, а нужна строка – используй getAbsolutePath(). Пример:

 
String path = "c:/a.txt";
File file = new File(path);
File file = new File("c:/a.txt");
String path = file.getAbsolutePath();

- Понял.

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

- Нет ничего проще, вот, смотри:

Код
//какой-то текущий файл
File originalFile = new File("c:/path/dir2/a.txt");

//объект-директория
File folder = originalFile.getParentFile();

//печать списка файлов на экран
for (File file : folder.listFiles())
{
 System.out.println(file.getName());
}

- Гм. Правильно.

- А, то! Немного путает, что и для файла и для директории используется один и тот же класс – File. Как то это не очень логично, мне кажется.

- Так исторически сложилось. Раньше директория была специальным «пустым» файлом на диске. Сейчас уже, конечно, многое изменилось, но не везде. У меня на сегодня все.

- Спасибо, за отличную лекцию, Билаабо.

2. Задачи на File

- Привет, Амиго! Я придумал тебе пару интересных задач.

Решать их можно только в Intellij IDEA. Вот, смотри, какие интересные условия…

Задачи
1. Проход по дереву файлов

1. На вход метода main подаются два параметра.
Первый - path - путь к директории, второй - resultFileAbsolutePath - имя файла, который будет содержать результат.
2. Для каждого файла в директории path и в ее всех вложенных поддиректориях выполнить следующее:
2.1. Если у файла длина в байтах больше 50, то удалить его.
2.2. Если у файла длина в байтах НЕ больше 50, то для всех таких файлов:
2.2.1. отсортировать их по имени файла в возрастающем порядке, путь не учитывать при сортировке
2.2.2. переименовать resultFileAbsolutePath в 'allFilesContent.txt'
2.2.3. в allFilesContent.txt последовательно записать содержимое всех файлов из п. 2.2.1. Тела файлов разделять "\n"
2.3. Удалить директории без файлов (пустые).
Все файлы имеют расширение txt.
2. Находим все файлы

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

3. Files, Path

- О, Риша, здорово!

- Привет, Амиго! Как жизнь?

- Отлично. Только что Билаабо рассказывал кучу интересного про File, и как с ним работать.

- Думаю, у меня как раз есть, что добавить по этой теме.

- Да? Тогда с удовольствием послушаю.

- Тогда слушай. Java постоянно развивается, постоянно ищутся новые способы делать различные вещи эффективнее. В Java 7 была добавлена альтернатива классу File.

- Альтернатива?

- Ага. Взяли за основу класс File, добавили в него немного нового, переименовывали методы, а в конце еще и разделили на два. Так что теперь есть два новых класса – Path и Files. Path – это, фактически новый аналог класса File, а Files – это утилитный класс (по аналогии с классами Arrays & Collections), в него вынести все статические методы класса File. Так «правильнее» с точки зрения ООП.

- Ну, раз с точки зрения ООП, то – ок. А что поменялось-то?

- Во-первых, отказались от дублирования методов, которые возвращали String и File. В классе Path все методы возвращают Path.

Во-вторых, убрали многие статические утилитные методы в класс Files.

В третьих, удобнее стало работать с относительными путями.

Вот список методов:

Методы класса PathОписание
boolean isAbsolute() Возвращает true, если путь – абсолютный.
Path getRoot() Возвращает корень текущего пути – директорию самого верхнего уровня.
Path getFileName() Возвращает имя файла из текущего пути.
Path getParent() Возвращает директорию из текущего пути.
boolean startsWith(Path other) Проверяет, что текущий путь начинается с переданного пути.
boolean endsWith(Path other) Проверяет, что текущий путь заканчивается на переданный путь.
Path normalize() Нормализует текущий путь. Например, приводит путь «c:/dir/dir2/../a.txt» к пути «c:/dir/a.txt»
Path relativize(Path other) Вычисляет относительный путь двух путей – «разницу путей»
Path resolve(String other) Восстанавливает абсолютный путь по текущему и относительному.
URI toUri() Возвращает URI текущего пути/файла.
Path toAbsolutePath() Приводит путь к абсолютному, если был относительный.
File toFile() Возвращает объект File, который соответствует текущему объекту Path.

- А текущий путь – это что?

- Это тот путь, который был передан в конструктор объекта Path, методы которого вызываются. Path – это «путь» по-английски.

- Ок. А какие методы есть у класса Files?

- Ну и куда же ты так спешишь-то? Сейчас все расскажу. Вот основные методы:

Методы класса FilesОписание
Path createFile(…) Создает файл на диске.
Path createDirectory(…) Создает директорию.
Path createDirectories(…) Создает директорию и поддиректории.
Path createTempFile(…) Создает «временный файл»
Path createTempDirectory(…) Создает «временную директорию»
void delete(Path path) Удаляет файл/директорию.
Path copy(Path source, Path target,…) Копирует файл.
Path move(Path source, Path target,…) Перемещает файл.
boolean isSameFile(Path, Path) Сравнивает два файла.
boolean isDirectory(Path) Путь - это директория?
boolean isRegularFile(Path) Путь – это файл?
long size(Path) Возвращает размер файла.
boolean exists(Path) Объект с таким именем существует?
boolean notExists(Path) Объект с таким именем не существует?
long copy(InputStream, OutputStream) Копирует байты из InputStream в OutputStream.
long copy(Path, OutputStream) Копирует все байты из Path в OutputStream.
long copy(InputStream, Path) Копирует все байты из InputStream в Path.
byte[] read(InputStream, int initialSize) Читает массив байт из InputStream.
byte[] readAllBytes(Path path) Читает все байты из InputStream.
List<String> readAllLines(Path path,..) Читает текстовый файл, возвращает список строк.
Path write(Path path, byte[] bytes,…) Пишет массив байт в файл.

- Как интересно, столько крутых функций, и все в одном месте.

А зачем нужны временные файлы?

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

- А сложно скачать файл из интернета?

- Очень просто. Смотри пример:

 Код
1
2
3
4
5
6
7
URL url = new URL("https://www.google.com.ua/images/srpr/logo11w.png");
InputStream inputStream = url.openStream();

Path tempFile = Files.createTempFile("temp-",".tmp");
Files.copy(inputStream, tempFile);

- И это все?

- Да, а что ты ожидал тут увидеть? Тут всего 4 строчки.

Строка номер 2. Создается объект URL, куда передается ссылка в интернете на файл с картинкой.

Строка номер 3. У объекта url открываться поток на чтение файла – InputStream.

Строка номер 5. С помощью метода createTempFile создается временный файл.

Строка номер 6. Метод Files.copy копирует данные из inputStream в tempFile. Все.

- Гениально!

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

Вот тебе, кстати, хорошая ссылка на этот материал:

Ссылка на материал

4. Задачи на Files, Path

- Привет, Амиго! Я придумал тебе пару интересных задач.

Решать их можно только в Intellij IDEA. Вот, смотри, какие интересные условия…

Задачи
1. Своя реализация

Реализуйте логику методов:
1. readBytes - должен возвращать все байты файла fileName
2. readLines - должен возвращать все строки файла fileName. Используйте дефолтовую кодировку
3. writeBytes - должен записывать массив bytes в файл fileName
4. copy - должен копировать файл resourceFileName на место destinationFileName

ГЛАВНОЕ УСЛОВИЕ:
Никаких других импортов!
2. Поиск скрытых файлов

В классе Solution переопределите логику двух методов:
-visitFile кроме своей логики должен добавлять в archived все пути к zip и rar файлам
-visitFileFailed должен добавлять в failed все пути к недоступным файлам и возвращать SKIP_SUBTREE

Пример вывода:
D:/mydir/BCD.zip

Метод main не участвует в тестировании.

5. FileInputStream, FileOutputStream, ZipOutputStream, ZipInputStream

- Привет, Амиго!

- Привет, Элли!

- Сегодня мы будем изучать потоки ввода-вывода.

- Да, я уже там все знаю. Это делается с помощью классов FileInputStream и FileOutputStream.

- Да, а какие методы есть у этих классов, знаешь?

- Конечно, вот методы FileInputStream:

МетодОписание
int read() Читает один байт и возвращает его.
int read(byte b[]) Читает массив байт, возвращает количество.
int read(byte b[], int off, int len) Читает из потока массив байт.
long skip(long n) Пропускает n байт, используется при чтении из потока.
int available() Возвращает количество байт, которое еще можно прочитать из потока.
void close() Закрывает поток.

- Все верно! А методы FileOutputStream?

- Вот:

МетодОписание
void write(int b) Записывает один байт в поток.
void write(byte b[]) Записывает массив байт в поток.
void write(byte b[], int off, int len) Записывает массив байт в поток.
void close() Закрывает поток.

- Амиго, ты меня удивляешь!

- А то!

- Отлично, тогда дам тебе два новых класса ZipInputStream и ZipOutputStream.

- Zip? Это как zip-архив?

- Именно. Эти потоки предназначены для работы с файлами, которые являются zip-архивами. С помощью них можно что-то читать прямо из zip-фала или писать в него!

- Ух ты! Как интересно. Но ведь в zip-архиве может быть не один файл, как же они работают?

- А для этого есть еще один специальный класс – ZipEntry. Он представляет файл, хрянящийся в архиве. Из ZipInputStream можно читать только объекты типа ZipEntry, а в ZipOutputStream можно писать только объекты ZipEntry. А вот сами ZipEntry как раз можно читать и писать как обычные файлы.

- А можно пример, как это работает?

- Конечно, вот пример, где мы создаем архив и кладем в него файл:

Код
// создаем архив
FileOutputStream zipFile = new FileOutputStream("c:/archive.zip");
ZipOutputStream zip = new ZipOutputStream(zipFile);

//кладем в него ZipEntry – «архивный объект»
zip.putNextEntry(new ZipEntry("document.txt"));

//копируем файл «document-for-archive.txt» в архив под именем «document.txt»
File file = new File("c:/document-for-archive.txt");
Files.copy(file.toPath(), zip);

// закрываем архив
zip.close();

- Как интересно. А разархивировать файлы так же легко?

- Ага. Вот тебе краткое описание методов классов ZipEntry, ZipInputStream и ZipOutputStream

ZipInputStream – это поток, поэтому все ZipEntry могут быть прочитаны только последовательно. Вот его методы:

МетодОписание
ZipEntry getNextEntry() Возвращает объект, описывающий следующий ZipEntry (пропускает все байты текущего entry).
void closeEntry() Закрывает чтение текущего ZipEntry (пропускает все байты текущего entry).
int available() Возвращает 1, если есть доступные ZipEntry, иначе 0.
int read(byte[] b, int off, int len) Читает байты из текущего ZipEntry.
long skip(long n) Пропускает n байт при чтении из потока.
void close() Закрывает поток.

- Не очень понятно.

- Лучше всего - это представить, что ты читаешь текстовый файл, а ZipEntry – это строки в нем. Можно читать как данные текущей строки – текущий ZipEntry, так и прыгать по строкам – getNextEntry, closeEntry.

- Вроде понятно, хотя не уверен, что правильно.

- ZipOutputStrem и его методы:

МетодОписание
void setComment(String comment) Устанавливает комментарий к архиву.
void setMethod(int method) Указывает метод (тип) сжатия.
void setLevel(int level) Указывает степень сжатия. Чем сильнее, тем медленнее.
void putNextEntry(ZipEntry e) Добавляет новый ZipEntry.
void closeEntry() Закрывает текущий ZipEntry.
void write(byte[] b, int off, int len) Пишет набор байт в текущий ZipEntry.
void close() Закрывает поток.

- А мы же в примере выше почти ничего этого не использовали.

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

- Гм. Тоже не плохо. А ZipEntry?

- Ага. В ZipEntry дополнительно хранится только служебная информация:

МетодОписание
String getName(), setName(String) Внутреннее имя файла.
long getTime(), setTime(long) Время последней модификации entry.
long getCRC(), setCRC(long) Контрольная сумма.
long getSize(), setSize(long) Размер до компрессии.
int getMethod(), setMethod(int) Метод сжатия.
long get/setCompressedSize() Размер после архивации.
boolean isDirectory() Является ли entry директорией.

- Выглядит не сложно и интересно, что не может не радовать!

- Отлично, тогда Диего даст тебе задачи и на эту тему.

- Язык мой – враг мой.

6. Задачи

- Привет, Амиго! Я придумал тебе пару интересных задач.

Решать их можно только в Intellij IDEA. Вот, смотри, какие интересные условия…

Задачи
1. Добавление файла в архив

В метод main приходит список аргументов.
Первый аргумент - полный путь к файлу fileName.
Второй аргумент - путь к zip-архиву.
Добавить файл (fileName) внутрь архива в директорию 'new'.
Если в архиве есть файл с таким именем, то заменить его.

Пример входных данных:
C:/result.mp3
C:/pathToTest/test.zip


Файлы внутри test.zip:
a.txt
b.txt


После запуска Solution.main архив test.zip должениметь такое содержимое:
new/result.mp3
a.txt
b.txt

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

В метод main приходит список аргументов.
Первый аргумент - имя результирующего файла resultFileName, остальные аргументы - имена файлов fileNamePart.
Каждый файл (fileNamePart) - это кусочек zip архива. Нужно разархивировать целый файл, собрав его из кусочков.
Записать разархивированный файл в resultFileName.
Архив внутри может содержать файл большой длины, например, 50Mb.
Внутри архива может содержаться файл с любым именем.

Пример входных данных. Внутри архива находится один файл с именем abc.mp3:
C:/result.mp3
C:/pathToTest/test.zip.003
C:/pathToTest/test.zip.001
C:/pathToTest/test.zip.004
C:/pathToTest/test.zip.002

7. Reader, Writer

- Привет, Амиго, еще раз.

- И тебе привет, Риша. О чем будет сегодняшняя лекция?

- Сегодня я тебе расскажу про Reader и Writer.

- Но, Риша, я же уже почти все о них знаю!

- Повторение мать учения.

- Гм. Ну, ок.

- Reader и Writer – это аналоги InputStream и OutputStream, но в отличие от них, они работают не с байтами, а с символами. Иногда их еще называют символьными потоками, в противовес InputStream и OutputStream – байтовым потокам.

- Один символ – два байта, я помню.

- Дело не только в этом. Эти классы специально ориентированы для работы с текстом и строками. Сегодня мы рассмотрим две классические реализации этих абстрактных классов – классы FileReader и FileWriter.

Вот методы класса FileReader:

МетодОписание
int read() Читает один символ из потока и возвращает его.
int read(char cbuf[], int offset, int length) Читает массив символов, возвращает количество прочитанных символов.
boolean ready() Возвращает true, если из потока еще можно читать.
void close() Закрывает поток для чтения.
int read(java.nio.CharBuffer target) Читает набор символов в буфер.
int read(char cbuf[]) Читает массив символов.
long skip(long n) Пропускает n символов в потоке.
String getEncoding() Возвращает текущую кодировку потока.

- Ну, я почти все это знаю. А FileWriter?

МетодОписание
void write(int c) Пишет один символ в поток.
void write(char cbuf[], int off, int len) Пишет массив символов в поток.
void write(char cbuf[]) Пишет массив символов в поток.
void write(String str, int off, int len) Пишет часть строки в поток.
void write(String str) Пишет строку в поток.
void flush() Записывает на диск, все для оптимизации хранится в памяти.
void close() Закрывает поток.
String getEncoding() Возвращает текущую кодировку потока.

И это знаю!

- Да, но это же отлично. Тогда давай разберем один интересный пример, а Диего потом даст тебе еще задач.

Как прочитать файл построчно? Сможешь написать код?

- Легко, смотри:

Код
//создаем список для хранения строк
List<String> list = new ArrayList<String>();

// открываем файл
File file = new File("c:/document.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));

//пока файл не пуст – читаем из него
while (reader.ready())
{
 list.add(reader.readLine());
}

//закрываем файл
reader.close();

- Гм. Неплохо.

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

- Ну, например, можно сделать так:

Код Ришы
File file = new File("c:/document.txt");

List<String> list = Files.readAllLines(file.toPath(), Charset.defaultCharset());

- Гм. Действительно короче. И ведь только сегодня вы мне рассказывали про все эти методы. Буду отрабатывать. Спасибо за урок, Риша.

- Удачи, Амиго.

8. Задачи

- Привет, Амиго! Я придумал тебе пару интересных задач.

Решать их можно только в Intellij IDEA. Вот, смотри, какие интересные условия…

Задачи
1. Null Object Pattern

Почитайте на вики про паттерн "Null Object"
Используйте Files, чтобы в конструкторе класса Solution правильно инициализировать поле fileData объектом ConcreteFileData.
Если возникли какие-то проблемы со чтением файла по пути pathToFile, то инициализируйте поле объектом NullFileData.
2. Исследуем Path

Почитайте про все методы класса Path.
Найдите такой, который создает относительный путь между текущим и переданным путем.
Реализуйте логику метода getDiffBetweenTwoPaths, он должен возвращать относительный путь.
Метод main не участвует в тестировании.

9. Properties

- Сегодня мы изучаем еще одну новую и интересную тему – свойства (properties).

В Java принято делать программы гибкими и легко настраиваемыми. Иногда еще говорят легко конфигурируемыми (от конфигурация).

Например, твоя программа раз в час копирует файлы из некоторой директории, архивирует их и отсылает тебе на email. Для этого программе надо знать директорию, откуда брать файлы и email, куда их посылать. Такие данные принято хранить не в коде программы, а в отдельных файлах свойств – properties-файлах.

Данные в таком файле хранятся в виде пар ключ-значение, разделенные знаком равно.

Пример
Файл data.properties
directory=c:/text/downloads
email=zapp@javarush.ru

Слева от знака равно – имя (ключ), справа – значение.

- Т.е. это что-то типа текстового представления HashMap?

- В общем-то, да.

Для удобной работы с такими файлами в Java есть специальный класс – Properties. Класс Properties унаследован от Hashtable<Object,Object>. Его даже можно рассматривать как HashTable, который умеет загружать себя из файла.

Вот его методы:

МетодОписание
void load(Reader reader) Загружает свойства из файла, представленного объектом Reader
void load(InputStream inStream) Загружает свойства из файла, представленного объектом InputStream
void loadFromXML(InputStream in) Загружает свойства из XML-файла
Object get(Object key) Возвращает значение по ключу. Метод унаследован от HashTable
String getProperty(String key) Возвращает значение свойства (строку) по ключу.
String getProperty(String key, String defaultValue) Возвращает значение свойства по ключу или defaultValue, если такого ключа нет.
Set<String> stringPropertyNames() Возвращает список всех ключей

Т.е. фактически тебе нужно выполнить всего две операции – загрузить в объект Properties данные из какого-нибудь файла, а затем получить эти свойства с помощью метода getProperty(). Ну и не забывай, что можешь пользоваться объектом Properties как HashMap.

Вот тебе пример:

Код
//файл, который хранит свойства нашего проекта
File file = new File("c:/data.properties");

//создаем объект Properties и загружаем в него данные из файла.
Properties properties = new Properties();
properties.load(new FileReader(file));

//получаем значения свойств из объекта Properties
String email = properties.getProperty("email");
String directory = properties.getProperty("directory");

//получаем числовое значение из объекта Properties
int maxFileSize = Integer.parseInt(properties.getProperty("max.size", "10000"));

- Ага. Т.е. мы создаем объект Properties, затем передаем в него файл. В метод load, а затем просто вызываем getProperty. Так?

- Ага.

- А ты еще говорил, что им можно пользоваться как HashMap? Что ты имел в виду?

- Класс Properties унаследован от Hashtable, а это – тот же HashMap, просто все методы его синхронизированы. Вот так можно просто вывести на экран все значения из файла свойств:

Код
//получаем файл со свойствами
File file = new File("c:/data.properties");

//создаем объект Properties и загружаем в него данные из файла.
Properties properties = new Properties();
properties.load(new FileReader(file));

//проходимся по всем ключам и печатаем все их значения на консоль
for (String key : properties.stringPropertyNames())
{
 System.out.println(properties.get(key));
}

- Ага. Вроде все стало на свои места. Спасибо, Риша, буду пользоваться такой крутой штукой.

10. Задачи

- Привет, Амиго! Вот, держи интересную задачу, решать ее можно только в Intellij IDEA.

Задачи
1. Читаем конфиги

Реализовать метод getProperties, который должен считывать свойства из переданного файла fileName.
fileName может иметь любое расширение - как xml, так и любое другое, или вообще не иметь.
Нужно обеспечить корректное чтение свойств.
При возникновении ошибок должен возвращаться пустой объект.
Метод main не участвует в тестировании.

Подсказка: возможно, Вам понадобится File.separator.

11. Учимся гуглить

- Привет, Амиго!

Продолжаем наши уроки – учимся гуглить.

Вот тебе несколько заданий:

 Найди в интернете:
1 Примеры работы с классом File
2 Как получить список всех файлов в директории и ее поддиректориях?
3 Как получить список всех файлов в директории с расширением zip?
4 Как заархивировать файл?
5 Как заархивировать много файлов?
6 Как заархивировать много файлов и директорий?
7 Как разархивировать файл?
8 Как задать кодировку файла?
9 Как узнать кодировку файла в архиве?
10 Как поменять данные (свойства) в объекте типа Properties?

12. Профессор дает доп. материал

- Привет, Амиго!

Вот тебе дополнительный материал по теме.

Ссылка на дополнительный материал

13. Хулио

- Привет, Амиго!

- Привет, Хулио.

- Вот недавно была презентация нового Ipad.

- Да, и что он умеет делать?

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

Оригинал видео на YouTube

14. Вопросы к собеседованию по этой теме

- Привет, Амиго!

 Вопросы к собеседованиям
1 Может ли объект File соответствовать файлу, которого еще нет?
2 Как преобразовать объект File к типу Path?
3 Зачем нужен класс Files?
4 Какие классы для архивации вы знаете?
5 Как добавить директорию в архив?
6 Зачем нужны Properties?
7 В каком виде хранятся данные в файле .properties?
8 Можно ли изменять данные в объекте Properties после загрузки их из файла?
9 Зачем нужен класс FileReader?
10 Зачем нужен класс FileWriter?

15. Большая задача

- Привет, Амиго!

- Здравия желаю, Капитан Бобров!

- Готов к новой секретной миссии?

- Конечно готов, сэр!

- Тогда вот тебе файл с инструкциями. Сегодня мы будем разрабатывать новую версию искусственного интеллекта. Человечеству нужна наша помощь. Мы обязаны спасти людей от гибели.

- Но, сэр! Я не могу открыть файл. Нужен архиватор.

- Да? Кхм… Тогда спасение человечества переносится. Напишем сегодня собственный архиватор.

- Товарищ Капитан, а как же люди?

- Ничего с ними не случится. Обратись за заданием к агенту Intellij IDEA, там получишь все инструкции.

- Разрешите приступить, сэр?

- Приступайте.