1. Класс Files

Класс Files

Чтобы работать с файлами, есть шикарный утилитный класс — java.nio.file.Files. У него есть методы просто на все случаи жизни. Все методы этого класса статические и работают с объектами типа Path. Методов очень много, поэтому мы рассмотрим только основные:

Метод Описание
Path createFile(Path path)
Создает новый файл с путем path
Path createDirectory(Path path)
Создает новую директорию
Path createDirectories(Path path)
Создает несколько директорий
Path createTempFile(prefix, suffix)
Создает временный файл
Path createTempDirectory(prefix)
Создает временную директорию
void delete(Path path)
Удаляет файл или директорию, если она пуста
Path copy(Path src, Path dest)
Копирует файл
Path move(Path src, Path dest)
Перемещает файл
boolean isDirectory(Path path)
Проверяет, что путь — это директория, а не файл
boolean isRegularFile(Path path)
Проверяет, что путь — это файл, а не директория
boolean exists(Path path)
Проверяет, что объект по заданному пути существует
long size(Path path)
Возвращает размер файла
byte[] readAllBytes(Path path)
Возвращает все содержимое файла в виде массива байт
String readString(Path path)
Возвращает все содержимое файла в виде строки
List<String> readAllLines(Path path)
Возвращает все содержимое файла в виде списка строк
Path write(Path path, byte[])
Записывает в файл массив байт
Path writeString(Path path, String str)
Записывает в файл строку
DirectoryStream<Path> newDirectoryStream(Path dir)
Возвращает коллекцию файлов (и поддиректорий) из заданной директории

2. Создание файлов и директорий

Файлы и директории создавать очень просто. Убедимся на примерах:

Код Примечание
Files.createFile(Path.of("c:\\readme.txt"));
Создает файл
Files.createDirectory(Path.of("c:\\test"));
Создает директорию
Files.createDirectories(Path.of("c:\\test\\1\\2\\3"));
Создает директорию и все нужные поддиректории, если их не существует.

3. Копирование, перемещение и удаление

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

Код Примечание
Path path1 = Path.of("c:\\readme.txt");
Path path2 = Path.of("c:\\readme-copy.txt");
Files.copy(path1, path2);
Копирует файл
Path path1 = Path.of("c:\\readme.txt");
Path path2 = Path.of("d:\\readme-new.txt");
Files.move(path1, path2);
Перемещает и переименовывает файл
Path path = Path.of("d:\\readme-new.txt");
Files.delete(path);
Удаляет файл

4. Проверка типа файла и факта существования

Когда у вас есть какой-то путь, полученный извне, вы бы хотели знать, это файл или директория. Ну и вообще: существует такой файл/директория или нет?

Для этого тоже есть специальные методы. Так же можно легко узнать длину файла:

Код Примечание
Files.isRegularFile(Path.of("c:\\readme.txt"));
true
Files.isDirectory(Path.of("c:\\test"));
true
Files.exists(Path.of("c:\\test\\1\\2\\3"));
false
Files.size(Path.of("c:\\readme.txt"));
10112

5. Работа с содержимым файла

И наконец, есть целая серия методов, которые позволяют легко прочитать или записать содержимое файла. Пример:

Код Описание
Path path = Path.of("c:\\readme.txt");
List<String> list = Files.readAllLines(path);

for (String str : list)
   System.out.println(str);

Читаем содержимое файла в виде списка строк.

Выводим строки на экран


6. Получение содержимого директории

Остался еще самый интересный метод — получение файлов и поддиректорий в заданной директории.

Для этого есть специальный метод — newDirectoryStream(), который возвращает специальный объект типа DirectoryStream<Path>. У него есть итератор(!), и с помощью этого итератора можно получить все файлы и поддиректории заданной директории.

Выглядит проще, чем кажется:

Код Описание
Path path = Path.of("c:\\windows");

try (DirectoryStream<Path> files = Files.newDirectoryStream(path)) {
   for (Path path : files)
      System.out.println(path);
}


Получаем объект со списком файлов
Цикл по списку файлов

Объект DirectoryStream<Path> обладает двумя свойствами. Во-первых, у него есть итератор, который возвращает пути к файлам, и мы можем этот объект использовать внутри цикла for-each.

А во-вторых, этот объект является потоком данных, и его нужно закрывать с помощью метода close(), ну или использовать внутри try-with-resources.



7. Метод Files.newInputStream

Начиная с Java 5 классы FileInputStream и FileOutputStream стали считаться устаревшими. Одним из их минусов было то, что при создании объекта этих классов сразу происходит создание файлов на диске. И потенциально выбрасываются все ошибки, связанные с созданием файлов.

Впоследствии это было признано не самым хорошим решением. Поэтому для создания объектов-файлов рекомендуется использовать методы утилитного класса – java.nio.Files.

Вот сравнение старого подхода к созданию файлов и нового:

Было
String src = "c:\\projects\\log.txt";
InputStream input = new FileInputStream( src );
Стало
String src = "c:\\projects\\log.txt";
InputStream input = Files.newInputStream( Path.of( src ) );

Аналогично замена и для FileOutputStream:

Было
String src = "c:\\projects\\log.txt";
OutputStream  output = new FileOutputStream( src );
Стало
String src = "c:\\projects\\log.txt";
OutputStream  output = Files.newOutputStream( Path.of( src ) );