Шаг 111.
Язык программирования Java.
Примеры использования класса Files

На этом шаге мы приведем несколько примеров использования класса Files


1 пример. Напишем программу, которая принимает на вход путь до папки, а также список расширений файлов и считает сколько файлов с заданными содержится в папке (с учетом всего дерева внутренних папок). Путь до папки и список расширений файлов передается через командную строку.

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;

public class Main {
    /**
     * Функция для проверки аргументов командной строки
     *
     * @param args аргументы командной строки
     * @return true, если мы корректно передали неообходимые аргументы,
     * и false в противном случае
     */
    private static boolean checkArgs(String[] args) {
        /* Проверяем что программе передан путь к файлу */
        if (args.length == 0) {
            System.out.println("Введите путь до папки");
            return false;
        }

        String dirName = args[0];
        Path dir = Paths.get(dirName);

        /* Проверяем наличие папки на диске */
        if (Files.notExists(dir)) {
            System.out.println("Данной папки не существует");
            return false;
        }

        return true;
    }

    /**
     * Функция для вывода информации по расширениям файлов
     *
     * @param counter Контейнер, содержащий информацию по расширениям файлов
     */
    private static void printExpansionsCount(Map<String, Integer> counter) {
        if (counter.size() == 0) {
            System.out.println("В данной папке нет файлов");
            return;
        }
     System.out.println("В данной папке существуют файлы со следующими расширениями");
        for (Map.Entry<String, Integer> entry : counter.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }

    private static void solve(String[] args) throws IOException {
        String dirName = args[0];
        Path dir = Paths.get(dirName);

        Map<String, Integer> counter = new HashMap<>();

        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 
                                                                  throws IOException {
                /* Если мы посетили очередной файл, то получаем его имя */
                String fileName = file.getFileName().toString();

                /* Проверяем есть ли у него расширение */
                if (fileName.indexOf('.') != -1) {
                    /* Если есть, то получаем расширение */
                    String expansion = fileName.substring(fileName.indexOf('.') + 1,
                                                          fileName.length());
                    /* Изменяет счетчик количества этого расширения */
                    int count = counter.getOrDefault(expansion, 0);
                    counter.put(expansion, count + 1);
                }
                return FileVisitResult.CONTINUE;
            }
        });

        /* Выводим информацию по расширениям файлов */
        printExpansionsCount(counter);
    }

    public static void main(String[] args) throws IOException {
        /* Проверяем аргументы командной строки */
        if (checkArgs(args)) {
            solve(args);
        }
    }
}

Проект можно взять здесь


Рис. 1. Вывод программы


2 пример. Напишем программу, которая копирует содержимое заданной папки (с учетом всего дерева внутренних папок) в другую папку. Все пути передаются через командную строку.

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;

public class Main {

    /**
     * Функция для проверки аргументов командной строки
     *
     * @param args аргументы командной строки
     * @return true, если мы корректно передали неообходимые аргументы,
     * и false в противном случае
     */
    private static boolean checkArgs(String[] args) {
        if (args.length == 0) {
            System.out.println("Введите путь до папки, содержимое которой хотите 
                                                                        скопировать");
            return false;
        }

        if (args.length == 1) {
            System.out.println("Введите путь до папки, в которую хотите скопировать 
                                                          содержимое исходной папки");
            return false;
        }

        String dirSourceName = args[0];
        Path dirSource = Paths.get(dirSourceName);
        if (Files.notExists(dirSource)) {
            System.out.println("Папка " + dirSourceName + " не существует");
            return false;
        }

        if (!Files.isDirectory(dirSource)) {
            System.out.println("Введите путь до папки, содержимое которой хотите 
                                                                        скопировать");
            return false;
        }

        String dirTargetName = args[1];
        Path dirTarget = Paths.get(dirTargetName);
        if (Files.notExists(dirTarget)) {
            System.out.println("Папка " + dirTargetName + " не существует");
            return false;
        }

        if (!Files.isDirectory(dirTarget)) {
            System.out.println("Введите путь до папки, в которую хотите скопировать 
                                                          содержимое исходной папки");
            return false;
        }

        return true;
    }

    private static void solve(String[] args) throws IOException {
        String dirSourceName = args[0];
        String dirTargetName = args[1];

        Path dirSource = Paths.get(dirSourceName);
        Path dirTarget = Paths.get(dirTargetName);

        Files.walkFileTree(dirSource, new SimpleFileVisitor<Path>() {
            private void copyObject(Path source) throws IOException {
                if (!Files.isSameFile(source, dirSource)) {
                    /* Получаем путь объекта относительно исходной папки */
                    Path subPath = source.subpath(dirSource.getNameCount(), 
                                                               source.getNameCount());
                    System.out.print("Копирование " + subPath.toString() + " - ");

                    /* Определяем путь нового объекта */
                    String targetName = dirTarget.toAbsolutePath().toString() + "/" + 
                                                                   subPath.toString();

                    try {
                        /* Копируем объект */
                        Files.copy(source, Paths.get(targetName), 
                                                 StandardCopyOption.REPLACE_EXISTING);
                        System.out.println("успешно");
                    } catch (DirectoryNotEmptyException e) {
                        System.out.println("неуспешно");
                    }
                }
            }

            @Override public
            FileVisitResult preVisitDirectory(Path dir, 
                                              BasicFileAttributes attrs) throws 
                                                                         IOException {
                copyObject(dir);

                return FileVisitResult.CONTINUE;
            }

            @Override public
            FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 
                                                                  throws IOException {
                copyObject(file);

                return FileVisitResult.CONTINUE;
            }
        });
    }

    public static void main(String[] args) throws IOException {
        if (checkArgs(args)) {
            solve(args);
        }
    }
}

Проект можно взять здесь


Рис. 2. Вывод программы


3 пример. Напишем программу, которая считает количество слов и пробелов в заданном файле. Путь до файла передается через командную строку.

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

public class Main {

    /**
     * Функция для проверки аргументов командной строки
     *
     * @param args аргументы командной строки
     * @return true, если мы корректно передали неообходимые аргументы,
     * и false в противном случае
     */
    private static boolean checkArgs(String[] args) {
        if (args.length == 0) {
            return false;
        }

        Path file = Paths.get(args[0]);
        if (Files.notExists(file)) {
            return false;
        }

        return true;
    }

    private static void solve(String[] args) throws IOException {
        Path file = Paths.get(args[0]);
        /* Читаем все строки из файла */
        List<String> lines = Files.readAllLines(file);

        int countSpaces = 0;
        int countWords = 0;

        for (String line : lines) {

            /* Считаем сколько пробелов в конце строки */
            int lasti = line.length() - 1;
            while (lasti >= 0 && line.charAt(lasti) == ' ') {
                countSpaces++;
                lasti--;
            }

            /* Считаем сколько пробелов в начале строки */
            int firsti = 0;
            while (firsti < lasti && line.charAt(firsti) == ' ') {
                countSpaces++;
                firsti++;
            }

            /* Убираем пробелы с обеих сторон строки */
            line = line.trim();

            if (line.length() != 0) {
                /* Количество слов на 1 больше чем количество пробельных блоков */
                countWords++;
            }

            for (int i = 0; i < line.length(); i++) {
                if (line.charAt(i) == ' ') {
                    /* Если мы достигли пробела, то увеличиваем счетчик количества
                                                                           пробелов */
                    countSpaces++;

                    /* Если предыдущий символ был не пробел, то увеличиваем счетчик 
                                                                    количества слов */
                    if (i > 0 && line.charAt(i - 1) != ' ') {
                        countWords++;
                    }
                }
            }
        }

        /* Выводим полученный результат */
        System.out.println("Количество пробелов: " + countSpaces);
        System.out.println("Количества слов: " + countWords);
    }

    public static void main(String[] args) throws IOException {
        if (checkArgs(args)) {
            solve(args);
        }
    }
}

Проект можно взять здесь


Рис. 3. Вывод программы

На следующем шаге мы начнем изучать функциональное программирование в Java

Предыдущий шаг Содержание Следующий шаг