Работа с файловой системой в Java: от File до NIO
Работа с файловой системой — одна из фундаментальных задач в разработке на Java. Будь то чтение конфигураций, запись логов или обработка пользовательских данных, умение правильно взаимодействовать с файлами и директориями необходимо каждому Java-разработчику. В этой статье мы подробно разберём основные классы и подходы для работы с файловой системой, начиная с классического java.io.File и заканчивая современным java.nio.file.
Класс File: основы работы с файлами и папками
Класс java.io.File существует в Java с самой первой версии и предоставляет базовые возможности для работы с путями, файлами и директориями. Он не читает и не пишет данные напрямую, но позволяет выполнять операции по управлению файловой системой.
Создание объекта File и проверка существования:
import java.io.File;
public class FileExample {
public static void main(String[] args) {
File file = new File("example.txt");
File dir = new File("myFolder");
System.out.println("Файл существует: " + file.exists());
System.out.println("Это директория: " + dir.isDirectory());
}
}
Создание файлов и директорий:
File newFile = new File("newFile.txt");
if (newFile.createNewFile()) {
System.out.println("Файл создан: " + newFile.getName());
} else {
System.out.println("Файл уже существует");
}
File newDir = new File("newDirectory");
if (newDir.mkdir()) {
System.out.println("Папка создана");
}
// Создать вложенные директории
File nestedDir = new File("parent/child/grandchild");
if (nestedDir.mkdirs()) {
System.out.println("Вложенные папки созданы");
}
Получение информации о файле:
File infoFile = new File("example.txt");
System.out.println("Абсолютный путь: " + infoFile.getAbsolutePath());
System.out.println("Размер: " + infoFile.length() + " байт");
System.out.println("Последнее изменение: " + infoFile.lastModified());
System.out.println("Родительская папка: " + infoFile.getParent());
Удаление и переименование:
File fileToDelete = new File("temp.txt");
if (fileToDelete.delete()) {
System.out.println("Файл удалён");
}
File oldFile = new File("old.txt");
File newFile = new File("new.txt");
if (oldFile.renameTo(newFile)) {
System.out.println("Файл переименован");
}
Чтение и запись файлов: классические потоки ввода-вывода
Для непосредственного чтения и записи данных используются потоки ввода-вывода (I/O streams). Основные классы: FileInputStream, FileOutputStream для байтовых данных и FileReader, FileWriter для текстовых.
Запись текста в файл с помощью FileWriter:
import java.io.FileWriter;
import java.io.IOException;
public class WriteExample {
public static void main(String[] args) {
try (FileWriter writer = new FileWriter("output.txt")) {
writer.write("Привет, мир!\n");
writer.write("Это вторая строка.");
System.out.println("Запись выполнена успешно");
} catch (IOException e) {
System.err.println("Ошибка записи: " + e.getMessage());
}
}
}
Чтение текста из файла с помощью FileReader и BufferedReader:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadExample {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("output.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.err.println("Ошибка чтения: " + e.getMessage());
}
}
}
Копирование файла с помощью байтовых потоков:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyFile {
public static void main(String[] args) {
try (FileInputStream in = new FileInputStream("source.jpg");
FileOutputStream out = new FileOutputStream("copy.jpg")) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
System.out.println("Файл скопирован");
} catch (IOException e) {
System.err.println("Ошибка копирования: " + e.getMessage());
}
}
}
Современный подход: NIO.2 (java.nio.file)
Начиная с Java 7, появился пакет java.nio.file, который предлагает более мощный и удобный API для работы с файловой системой. Основные классы: Path, Files, Paths.
Создание и использование Path:
import java.nio.file.Path;
import java.nio.file.Paths;
public class PathExample {
public static void main(String[] args) {
Path path = Paths.get("folder", "subfolder", "file.txt");
System.out.println("Путь: " + path);
System.out.println("Корень: " + path.getRoot());
System.out.println("Родитель: " + path.getParent());
System.out.println("Имя файла: " + path.getFileName());
System.out.println("Количество элементов: " + path.getNameCount());
}
}
Чтение и запись с помощью Files:
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class FilesExample {
public static void main(String[] args) throws Exception {
Path path = Paths.get("nio_example.txt");
// Запись строк в файл
List<String> lines = List.of("Первая строка", "Вторая строка", "Третья строка");
Files.write(path, lines);
System.out.println("Файл записан");
// Чтение всех строк из файла
List<String> readLines = Files.readAllLines(path);
readLines.forEach(System.out::println);
}
}
Работа с директориями и обход файловой системы:
import java.nio.file.*;
import java.io.IOException;
import java.util.stream.Stream;
public class DirectoryWalkExample {
public static void main(String[] args) {
Path startDir = Paths.get(".");
// Обход всех файлов и папок рекурсивно
try (Stream<Path> stream = Files.walk(startDir, 2)) {
stream.filter(Files::isRegularFile)
.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
// Поиск файлов по маске
try (Stream<Path> stream = Files.find(startDir, 3,