Шаг 86.
Язык программирования Java.
Класс File

На этом шаге мы рассмотрим класс File

Большинство классов, определенных в пакете java.io, оперируют потоками ввода-вывода, чего нельзя сказать о классе File. Он оперирует непосредственно файлами и взаимодействует с файловой системой. В классе File не определено, каким образом данные извлекаются и сохраняются в файлах, но описываются свойства самих файлов. Объект класса File служит для получения таких сведений о файле на диске, как права доступа, время, дата и путь к каталогу, или манипулирование этими сведениями, а также для перемещения по иерархиям подкаталогов.

Файлы служат первичными источниками и адресатами данных во многих программах. Файлы являются центральным ресурсом для хранения постоянной и обмениваемой информации. Каталог в Java интерпретируется как объект класса File с единственным дополнительным свойством – список имен файлов, которые могут быть получены методом list().

Для создания объектов класса File можно воспользоваться следующими конструкторами:

public File(String pathname);
public File(String pathname, String name);
public File(File file, String name);
public File(URI uri);

Параметр pathname обозначает путь к файлу, параметр name – имя конкретного файла или подкаталога, параметр file – объект типа File, задающий каталог, а параметр uri – объект типа URI, описывающий файл.

В таблице 1 перечислены основные функции для работы с файлами и папками.

Таблица 1. Функции для получения информации по директории или файлу
Функция Описание
boolean exists() Проверяет наличие файла или директории
File getAbsoluteFile() Аналогична следующей записи: new File(this.getAbsolutePath())
String getAbsolutePath() Возвращает полный путь до файла
String getName() Возвращает имя файла
boolean isDirectory() Проверяет является ли рассматриваемый объект директорией. Возвращает true, в случае успеха, и false в противном случае.
boolean isFile() Проверяет является ли рассматриваемый объект файлом. Возвращает true, в случае успеха, и false в противном случае.
long length() Возвращает размер файла или папки. Если файл отсутствует возвращает 0L.
String[] list() Возвращает массив имен директорий и файлов в рассматриваемой директории. В случае если данная функция была вызвана для файла, то вернется значение null.
String[] list(FilenameFilter filter) Возвращает массив имен директорий и файлов с заданным фильтром в рассматриваемой директории. В случае если данная функция была вызвана для файла, то вернется значение null.
File[] listFiles() Возвращает массив объектов File, в котором хранится информация обо всех файлах и директорий для заданной директории. Если данная функция была вызвана для файла, то вернется значение null.
File[] listFiles(FileFilter filter) Возвращает массив объектов File, в котором хранится информация обо всех файлах и директорий для заданной директории с заданным фильтром. Если данная функция была вызвана для файла, то вернется значение null.
File[] listFiles(FilenameFilter filter) Возвращает массив объектов File, в котором хранится информация обо всех файлах и директорий для заданной директории с заданным фильтром. Если данная функция была вызвана для файла, то вернется значение null.


Напишем несколько программ для демонстрации использования класса File.


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

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * Первый пример использования класса File
 * */
public class Main {
    public static void main(String[] args) {
        /*Провераяем, что мы передали папку программе*/
        if (args.length == 0) {
            System.out.println("Введите путь до папки");
            return;
        }

        String pathName = args[0];

        /*Конструируем объект File*/
        File root = new File(pathName);

        /*Проверяем, что ме передали существующую папку*/
        if (!root.exists()) {
            System.out.println("Заданная папка не существует");
            return;
        }

        /*Здесь мы будем хранить все файлы в нашей папке*/
        List<File> files = new ArrayList<>();

        /*Здесь мы будем хранить все подпапки в нашей папке*/
        List<File> directories = new ArrayList<>();

        /*Обойдем все объекты в нашей папке*/
        for (File object : root.listFiles()) {
            if (object.isDirectory()) {
                /*Если объект - папка, то добавим в лист directories*/
                directories.add(object);
            } else {
                /*Иначе добавим в лист files*/
                files.add(object);
            }
        }

        /*Выводим список подпапок*/
        System.out.println("Список подпапок в папке \"" + pathName + "\"");
        for (File directory : directories) {
            System.out.println(directory.getName());
        }

        /*Выводим список файлов*/
        System.out.println("\nСписок файлов в папке \"" + pathName + "\"");
        for (File file : files) {
            System.out.println(file.getName());
        }
    }
}

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


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


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

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Первый пример использования класса File
 * */

public class Main {
    /**
     * Лист для хранения расширений файлов
     * */
    private static List<String> extensions = new ArrayList<>();

    /**
     * Счетчик количества файлов с определенным расширением
     * */
    private static Map<String, Integer> counter = new HashMap<>();

    /**
     * Имя корневой папки
     * */
    private static String rootName;

    /**
     * Объект класса File, содержащий сведенья о корневой папке
     * */
    private static File root;

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

        rootName = args[0];
        root = new File(rootName);
        /*Проверяем, что ме передали путь к существующей папке*/
        if (!root.exists()) {
            System.out.println("Заданная папка не существует");
            return false;
        }

        /*Проверяем, что мы передали хотябы одно расширение файлов*/
        if (args.length == 1) {
            System.out.println("Введите расширения для поиска файлов");
            return false;
        }

        return true;
    }

    /**
     * Функция для заполнения списка расширений и инициализация счетчика вхождений 
     *                                                                     расширений
     * @param args аргументы командной строки
     * */
    private static void buildExtensions(String[] args) {
        for (int i = 1; i < args.length; i++) {
            extensions.add(args[i]);
            counter.put(args[i], 0);
        }
    }

    /**
     * Функция для подсчета файлов с заданными рассширениями
     * */
    private static void countOfExpansions() {
        /*Обойдем все объекты в нашей папке*/
        for (File object : root.listFiles()) {
            if (object.isFile()) {
                /*Проверим для каждого расширения*/
                for (String extension : extensions) {
                    /*Если наш файл имеет рассширение extension*/
                    if (object.getName().endsWith("." + extension)) {
                        /*то изменим значение количество у этого расширения*/
                        Integer countFiles = counter.get(extension);
                        counter.replace(extension, countFiles + 1);
                        break;
                    }
                }
            }
        }
    }

    /**
     * Функция для вывода информации о количестве файлов с заданными расширениями
     * */
    private static void printCounter() {
        for (Map.Entry<String, Integer> entry : counter.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }

    public static void main(String[] args) {
        /*Если мы правильно передали программе аргументы*/
        if (checkArgs(args)) {
            /*Строим список расширений*/
            buildExtensions(args);

            /*Считаем количество вхождений файлов с заданными расширениями*/
            countOfExpansions();

            /*Выводим результат на экран*/
            printCounter();
        }
    }
}

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


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


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

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Первый пример использования класса File
 * */

public class Main {
    /**
     * Лист для хранения расширений файлов
     * */
    private static List<String> extensions = new ArrayList<>();

    /**
     * Счетчик количества файлов с определенным расширением
     * */
    private static Map<String, Integer> counter = new HashMap<>();

    /**
     * Имя корневой папки
     * */
    private static String rootName;

    /**
     * Объект класса File, содержащий сведенья о корневой папке
     * */
    private static File root;

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

        rootName = args[0];
        root = new File(rootName);
        /*Проверяем, что ме передали путь к существующей папке*/
        if (!root.exists()) {
            System.out.println("Заданная папка не существует");
            return false;
        }

        /*Проверяем, что мы передали хотябы одно расширение файлов*/
        if (args.length == 1) {
            System.out.println("Введите расширения для поиска файлов");
            return false;
        }

        return true;
    }

    /**
     * Функция для заполнения списка расширений и инициализация счетчика вхождений 
     *                                                                     расширений
     * @param args аргументы командной строки
     * */
    private static void buildExtensions(String[] args) {
        for (int i = 1; i < args.length; i++) {
            extensions.add(args[i]);
            counter.put(args[i], 0);
        }
    }

    /**
     * Функция для подсчета файлов с заданными рассширениями в текущей директории
     * @param directory текущая директория
     * */
    private static void countOfExpansions(File directory) {
        /*Обойдем все объекты в нашей папке*/
        for (File object : directory.listFiles()) {
            if (object.isFile()) {
                /*Проверим для каждого расширения*/
                for (String extension : extensions) {
                    /*Если наш файл имеет рассширение extension*/
                    if (object.getName().endsWith("." + extension)) {
                        /*то изменим значение количество у этого расширения*/
                        Integer countFiles = counter.get(extension);
                        counter.replace(extension, countFiles + 1);
                        break;
                    }
                }
            } else {
                countOfExpansions(object);
            }
        }
    }

    /**
     * Функция для вывода информации о количестве файлов с заданными расширениями
     * */
    private static void printCounter() {
        for (Map.Entry<String, Integer> entry : counter.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }

    public static void main(String[] args) {
        /*Если мы правильно передали программе аргументы*/
        if (checkArgs(args)) {
            /*Строим список расширений*/
            buildExtensions(args);

            /*Считаем количество вхождений файлов с заданными расширениями*/
            countOfExpansions(root);

            /*Выводим результат на экран*/
            printCounter();
        }
    }
}

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


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


На следующем шаге мы продолжим изучение этого вопроса

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