«1. Обзор

В этом руководстве мы дадим обзор класса File, который является частью API java.io. Класс File дает нам возможность работать с файлами и каталогами в файловой системе.

2. Создание объекта File

Класс File имеет 4 общедоступных конструктора. В зависимости от потребностей разработчика могут быть созданы различные типы экземпляров класса File.

    File(String pathname) — создает экземпляр, представляющий заданный путь File(String parent, String child) — создает экземпляр, представляющий путь, образованный соединением родительского и дочернего путей File(File parent, String child) — создает экземпляр с путем, образованным путем соединения родительского пути, представленного другим экземпляром File, и дочернего пути File(URI uri) — создает экземпляр, представляющий данный унифицированный идентификатор ресурса

3. Работа с классом File

Класс File имеет ряд методов, которые позволяют нам работать с файлами в файловой системе и манипулировать ими. Мы выделим здесь некоторые из них. Важно отметить, что класс File не может изменять или получать доступ к содержимому файла, который он представляет.

3.1. Создание и удаление каталогов и файлов

Класс File имеет методы экземпляра для создания и удаления каталогов и файлов. Каталоги и файлы создаются с помощью методов mkdir и createNewFile соответственно.

Каталоги и файлы удаляются методом удаления. Все эти методы возвращают логическое значение, которое является истинным, если операция выполнена успешно, и ложным в противном случае:

@Test
public void givenDir_whenMkdir_thenDirIsDeleted() {
    File directory = new File("dir");
    assertTrue(directory.mkdir());
    assertTrue(directory.delete());
}

@Test
public void givenFile_whenCreateNewFile_thenFileIsDeleted() {
    File file = new File("file.txt");
    try {
        assertTrue(file.createNewFile());
    } catch (IOException e) {
        fail("Could not create " + "file.txt");
    }
    assertTrue(file.delete());
}

В приведенном выше фрагменте мы также видим другие полезные методы.

Метод isDirectory можно использовать для проверки того, является ли файл, обозначенный предоставленным именем, каталогом, а метод isFile можно использовать, чтобы проверить, является ли файл, обозначенный предоставленным именем, файлом. И мы можем использовать метод exists, чтобы проверить, существует ли уже каталог или файл в системе.

3.2. Получение метаданных об экземплярах файлов

Класс File имеет ряд методов, которые возвращают метаданные об экземплярах файлов. Давайте посмотрим, как использовать методы getName, getParentFile и getPath:

@Test
public void givenFile_whenCreateNewFile_thenMetadataIsCorrect() {

    String sep = File.separator;

    File parentDir = makeDir("filesDir");

    File child = new File(parentDir, "file.txt");
    try {
        child.createNewFile();
    } catch (IOException e) {
        fail("Could not create " + "file.txt");
    }

    assertEquals("file.txt", child.getName());
    assertEquals(parentDir.getName(), child.getParentFile().getName());
    assertEquals(parentDir.getPath() + sep + "file.txt", child.getPath());

    removeDir(parentDir);
}

Здесь мы проиллюстрировали проверку метаданных о файле, созданном внутри каталога. Мы также показали, как найти родителя файла и относительный путь к этому файлу.

3.3. Установка разрешений для файлов и каталогов

Класс File имеет методы, которые позволяют вам устанавливать разрешения для файла или каталога. Здесь мы рассмотрим методы setWritable и setReadable:

@Test
public void givenReadOnlyFile_whenCreateNewFile_thenCantModFile() {
    File parentDir = makeDir("readDir");

    File child = new File(parentDir, "file.txt");
    try {
        child.createNewFile();
    } catch (IOException e) {
        fail("Could not create " + "file.txt");
    }
    child.setWritable(false);
    boolean writable = true;
    try (FileOutputStream fos = new FileOutputStream(child)) {
        fos.write("Hello World".getBytes()); // write operation
        fos.flush();
    } catch (IOException e) {
        writable = false;
    } finally {
        removeDir(parentDir);
    }
    assertFalse(writable);
}

В приведенном выше коде мы пытаемся выполнить запись в файл после того, как явно установили для него разрешения, блокирующие любую запись. Мы делаем это с помощью метода setWritable. Попытка записи в файл, когда запись в файл запрещена, приводит к возникновению исключения IOException.

Далее мы пытаемся читать из файла после установки для него разрешений, которые блокируют любое чтение. Чтения блокируются с помощью метода setReadable:

@Test
public void givenWriteOnlyFile_whenCreateNewFile_thenCantReadFile() {
    File parentDir = makeDir("writeDir");

    File child = new File(parentDir, "file.txt");
    try {
        child.createNewFile();
    } catch (IOException e) {
        fail("Could not create " + "file.txt");
    }
    child.setReadable(false);
    boolean readable = true;
    try (FileInputStream fis = new FileInputStream(child)) {
        fis.read(); // read operation
    } catch (IOException e) {
        readable = false;
    } finally {
        removeDir(parentDir);
    }
    assertFalse(readable);
}

Опять же, JVM выдаст исключение IOException при попытках прочитать файл, где чтение не разрешено.

3.4. Список файлов внутри каталога

Класс File имеет методы, которые позволяют нам отображать файлы, содержащиеся в каталоге. Точно так же каталоги также могут быть перечислены. Здесь мы рассмотрим методы list и list(FilenameFilter):

@Test
public void givenFilesInDir_whenCreateNewFile_thenCanListFiles() {
    File parentDir = makeDir("filtersDir");

    String[] files = {"file1.csv", "file2.txt"};
    for (String file : files) {
        try {
            new File(parentDir, file).createNewFile();
        } catch (IOException e) {
            fail("Could not create " + file);
        }
    }

    //normal listing
    assertEquals(2, parentDir.list().length);

    //filtered listing
    FilenameFilter csvFilter = (dir, ext) -> ext.endsWith(".csv");
    assertEquals(1, parentDir.list(csvFilter).length);

    removeDir(parentDir);
}

Мы создали каталог и добавили в него два файла — один с расширением csv, а другой с расширением txt. При перечислении всех файлов в каталоге мы получаем два файла, как и ожидалось. Когда мы фильтруем список, отфильтровывая файлы с расширением csv, мы получаем только один файл.

3.5. Переименование файлов и каталогов

Класс File имеет функцию переименования файлов и каталогов с помощью метода renameTo:

@Test
public void givenDir_whenMkdir_thenCanRenameDir() {

    File source = makeDir("source");
    File destination = makeDir("destination");
    boolean renamed = source.renameTo(destination);

    if (renamed) {
        assertFalse(source.isDirectory());
        assertTrue(destination.isDirectory());

        removeDir(destination);
    }
}

В приведенном выше примере мы создаем два каталога — исходный и целевой. Затем мы переименовываем исходный каталог в каталог назначения, используя метод renameTo. То же самое можно использовать для переименования файлов вместо каталогов.

3.6. Получение информации о дисковом пространстве

«Класс File также позволяет нам получать информацию о дисковом пространстве. Давайте посмотрим на демонстрацию метода getFreeSpace:

@Test
public void givenDataWritten_whenWrite_thenFreeSpaceReduces() {

    String home = System.getProperty("user.home");
    String sep = File.separator;
    File testDir = makeDir(home + sep + "test");
    File sample = new File(testDir, "sample.txt");

    long freeSpaceBefore = testDir.getFreeSpace();
    try {
        writeSampleDataToFile(sample);
    } catch (IOException e) {
        fail("Could not write to " + "sample.txt");
    }

    long freeSpaceAfter = testDir.getFreeSpace();
    assertTrue(freeSpaceAfter < freeSpaceBefore);

    removeDir(testDir);
}

В этом примере мы создали каталог внутри домашнего каталога пользователя, а затем создали в нем файл. Затем мы проверили, изменилось ли свободное место в разделе домашнего каталога после заполнения этого файла некоторым текстом. Другими методами, предоставляющими информацию о дисковом пространстве, являются getTotalSpace и getUsableSpace.

4. Заключение

В этом руководстве мы показали некоторые функциональные возможности, предоставляемые классом File для работы с файлами и каталогами в файловой системе. .

Как всегда, полный исходный код примера доступен на Github.