Всем привет. Это третья часть фильтрации файлов с использованием серии NIO.2. Для тех из вас, кто не читал Часть 1 или Часть 2 , вот резюме.
NIO.2 — это новый API для операций ввода-вывода, включенный в JDK начиная с Java 7. С этим новым API вы можете выполнять те же операции, что и с java.io, а также множество замечательных функций, таких как: Доступ к метаданным файла и просмотр для изменения каталога, среди других. Очевидно, что пакет java.io не исчезнет из-за обратной совместимости, но мы рекомендуем начать использовать NIO.2 для наших новых требований ввода / вывода. В этом посте мы увидим, как легко фильтровать содержимое каталога с помощью этого API. Для этого есть 3 способа, мы уже рассмотрели два аналогичных способа в части 1 и части 2 , но теперь мы увидим более мощный подход.
Что вам нужно
NetBeans 7+ или любая другая IDE, поддерживающая Java 7
Фильтрация содержимого каталога является обычной задачей в некоторых приложениях, а NIO.2 делает ее действительно простой. Классы и интерфейсы, которые мы собираемся использовать, описаны ниже:
- java.nio.file.Path : интерфейс, чьи объекты могут представлять файлы или каталоги в файловой системе. Это как java.io.File, но в NIO.2. Какую бы операцию ввода / вывода вы хотели выполнить, вам нужен экземпляр этого интерфейса.
- java.nio.file.DirectoryStream : интерфейс, объекты которого перебирают содержимое каталога.
- java.nio.file.DirectoryStream.filter <T> : вложенный интерфейс, объекты которого определяют, следует ли фильтровать элемент в каталоге или нет.
- java.nio.file.Files : класс со статическими методами, который работает с файлами, каталогами и т. д.
Мы собираемся фильтровать содержимое каталога, используя объекты, которые реализуют интерфейс java.nio.file.DirectoryStream.filter <T> . Этот интерфейс объявляет только один метод + accept (T): boolean, который, как говорит JavaDoc: «возвращает true, если запись каталога должна быть принята». Поэтому вам нужно реализовать этот метод и решить, следует ли принимать запись в каталоге, основываясь на любом атрибуте, который вы хотите использовать: по скрытому, по размеру, по владельцу, по дате создания и т. Д. Это важно помнить, используя это Метод, который вы больше не привязываете к фильтрации только по имени, вы можете использовать любой другой атрибут.
Если вам нужны только каталоги, вы можете использовать класс java.nio.file.Files и его + isDirectory (Path, LinkOption…): логический метод при создании фильтра:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
//in a class... /** * Creates a filter for directories only * @return Object which implements DirectoryStream.Filter * interface and that accepts directories only. */ public static DirectoryStream.Filter<Path> getDirectoriesFilter() { DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() { @Override public boolean accept(Path entry) throws IOException { return Files.isDirectory(entry); } }; return filter; } |
Или, если вам нужны только скрытые файлы, вы можете использовать класс java.nio.file.Files и его + isHidden (Path): логический метод при создании фильтра:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
//in a class... /** * Creates a filter for hidden files only * @return Object which implements DirectoryStream.Filter * interface and that accepts hidden files only. */ public static DirectoryStream.Filter<Path> getHiddenFilesFilter() { DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() { @Override public boolean accept(Path entry) throws IOException { return Files.isHidden(entry); } }; return filter; } |
Или, если вы хотите, чтобы файлы принадлежали конкретному пользователю, вы должны спросить пользователя и сравнить его с владельцем записи каталога. Чтобы получить владельца записи каталога, вы можете использовать класс java.nio.file.Files и его метод + getOwner (Path, LinkOption…): UserPrincipal ( обратите внимание, не все ОС поддерживают это).
Чтобы получить конкретного пользователя в файловой системе, используйте класс java.nio.file.FileSystem и его + getUserPrincipalLookupService () :
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
//in a class... /** * Creates a filter for owners * @return Object which implements DirectoryStream.Filter * interface and that accepts files that belongs to the * owner passed as parameter. */ public static DirectoryStream.Filter<Path> getOwnersFilter(String ownerName) throws IOException{ UserPrincipalLookupService lookup = FileSystems.getDefault().getUserPrincipalLookupService(); final UserPrincipal me = lookup.lookupPrincipalByName(ownerName); DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() { @Override public boolean accept(Path entry) throws IOException { return Files.getOwner(entry).equals(me); } }; return filter; } |
Следующий фрагмент кода определяет метод, который сканирует каталог, используя любой из предыдущих фильтров:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
//in a class... /** * Scans the directory using the filter passed as parameter. * @param folder directory to scan * @param filter Object which decides whether a * directory entry should be accepted */ private static void scan(String folder , DirectoryStream.Filter<Path> filter) { //obtains the Images directory in the app directory Path dir = Paths.get(folder); //the Files class offers methods for validation if (!Files.exists(dir) || !Files.isDirectory(dir)) { System.out.println( 'No such directory!' ); return ; } //validate the filter if (filter == null ) { System.out.println( 'Please provide a filter.' ); return ; } //Try with resources... so nice! try (DirectoryStream<Path> ds = Files.newDirectoryStream(dir, filter)) { //iterate over the filtered content of the directory int count = 0 ; for (Path path : ds) { System.out.println(path.getFileName()); count++; } System.out.println(); System.out.printf( '%d entries were accepted\n' , count); } catch (IOException ex) { ex.printStackTrace(); } } |
Мы можем выполнить предыдущий код, передав следующие параметры методу main (проверьте исходный код в конце этого поста):
- Каталог для сканирования: C: \ или / в зависимости от вашей ОС.
- Фильтр: скрытый
При выполнении кода мы получаем следующее:
В машине с Windows вы можете получить скрытые файлы, используя команду:
dir / AAH Обратите внимание, что мы получаем тот же результат:
И на моей виртуальной машине Linux:
Используя команду
ls -ald. * мы получаем похожие результаты:
Опять пиши один раз, беги везде!
Надеюсь, вам понравилась фильтрация файлов с использованием серии NIO.2. И последнее слово: все методы фильтрации, которые мы рассмотрели, работали только для одного каталога. Если вы хотите сканировать полное дерево каталогов, вам придется использовать
java.nio.file.SimpleFileVisitor class. Нажмите здесь, чтобы загрузить исходный код этого поста.
Ссылка: Java 7: Фильтрация файлов с использованием NIO.2 — Часть 3 от нашего партнера по JCG Алексиса Лопеса из блога Java и ME .