1. Обзор
В этом уроке мы дадим обзор класса File , который является частью java.io API. Класс File дает нам возможность работать с файлами и каталогами в файловой системе .
2. Создание объекта файла
Класс File имеет 4 открытых конструктора. В зависимости от потребностей разработчика могут быть созданы различные типы экземпляров класса File .
- Файл(строковый путь) – Создает экземпляр, представляющий заданный путь
- Файл(Родительская строка, дочерняя строка) – Создает экземпляр, представляющий путь, образованный путем соединения родительского и дочернего путей
- Файл(Родительский файл, дочерняя строка) – Создает экземпляр с путем, образованным путем соединения родительского пути, представленного другим Файлом экземпляром и дочерним путем
- Файл(URI uri) – Создает экземпляр, представляющий данный Единый идентификатор ресурса
3. Работа с классом File
Класс File имеет ряд методов, которые позволяют нам работать с файлами в файловой системе и манипулировать ими. Мы остановимся здесь на некоторых из них. Важно отметить, что класс File не может изменять или получать доступ к содержимому файла, который он представляет.
3.1. Создание и удаление каталогов и файлов
Класс File имеет методы экземпляра для создания и удаления каталогов и файлов. Каталоги и файлы создаются с использованием методов mkdir и create New File соответственно.
Каталоги и файлы удаляются с помощью метода delete //. Все эти методы возвращают логическое значение, которое является true при успешном выполнении операции и false в противном случае:
@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 имеет ряд методов, возвращающих метаданные об экземплярах 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 .