Статьи

Java 7: фильтрация файлов с использованием NIO.2 — часть 2

Всем привет. Это вторая часть фильтрации файлов с использованием серии NIO.2. Для тех из вас, кто не читал Часть 1 , вот резюме.

NIO.2 — это новый API для операций ввода-вывода, включенный в JDK начиная с Java 7. С этим новым API вы можете выполнять те же операции, что и с java.io, а также множество замечательных функций, таких как: Доступ к метаданным файла и просмотр для изменения каталога, среди других. Очевидно, что пакет java.io не исчезнет из-за обратной совместимости, но мы рекомендуем начать использовать NIO.2 для наших новых требований ввода / вывода. В этом посте мы увидим, как легко фильтровать содержимое каталога с помощью этого API. Для этого есть 3 способа, мы уже рассмотрели один из способов в части 1, и теперь мы увидим другой подход.

Что вам нужно

NetBeans 7+ или любая другая IDE, поддерживающая Java 7

JDK 7+

Фильтрация содержимого каталога является обычной задачей в некоторых приложениях, а NIO.2 делает ее действительно простой. Классы и интерфейсы, которые мы собираемся использовать, описаны ниже:

  • java.nio.file.Path : интерфейс, чьи объекты могут представлять файлы или каталоги в файловой системе. Это как java.io.File, но в NIO.2. Какую бы операцию ввода / вывода вы хотели выполнить, вам нужен экземпляр этого интерфейса.
  • java.nio.file.PathMatcher : интерфейс, который позволяет объектам выполнять операции сопоставления на путях.
  • java.nio.file.DirectoryStream : интерфейс, объекты которого перебирают содержимое каталога.
  • java.nio.file.Files : класс со статическими методами, который работает с файлами, каталогами и т. д.

Мы собираемся фильтровать содержимое каталога, используя объекты, которые реализуют интерфейс java.nio.file.PathMatcher . Мы можем получить один из этих объектов с помощью класса java.nio.file.Files , используя метод
+ getPathMatcher (String): PathMatcher . Этот метод поддерживает шаблоны ‘glob’ и ‘regex’. Вы можете проверить Часть 1 Фильтрации файлов, используя NIO.2 для получения дополнительной информации о ‘glob’ и для ‘regex’, посетите класс java.util.regex.Pattern . Шаблон сопоставляется с именами файлов, каталогов и т. Д., Которые находятся внутри каталога. Это важно помнить, используя этот метод, вы можете фильтровать только по имени файла, каталога и т. Д.

Например, если вы хотите фильтровать изображения .png и .jpg, вы должны использовать один из следующих синтаксиса и шаблона (обратите внимание на двоеточие между синтаксисом и шаблоном):

  • ‘Глоб:. * {PNG, JPG}’
  • ‘Регулярное выражение: ([^ \ s] + (\ (я) (PNG | JPG)) $.?)’

Конечно, синтаксис ‘glob’ намного проще, но у вас есть возможность использовать регулярные выражения для более детального соответствия. В любом случае, вам может быть интересно, почему вы должны использовать этот подход, если интерфейс java.nio.files.DirectoryStream позволяет вам фильтровать напрямую, используя ‘glob’ … Хорошо, давайте предположим, что у вас уже есть фильтр, но вам нужно выполнить больше, чем одна операция фильтрации, вот когда вам нужно использовать этот подход.

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

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//in a class...
 
    /**
     * Scans the directory using the patterns passed
     * as parameters.
     * Only 3 patterns will be used.
     * @param folder directory to scan
     * @param patterns The first pattern will be used
     * as the glob pattern for the DirectoryStream.    
     */
    private static void scan(String folder, String... patterns) {
        //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 at least the glob pattern
        if (patterns == null || patterns.length < 1) {
            System.out.println(
                'Please provide at least the glob pattern.');
            return;
        }
 
        //obtain the objects that implements PathMatcher
        PathMatcher extraFilterOne = null;
        PathMatcher extraFilterTwo = null;
        if (patterns.length > 1 && patterns[1] != null) {
            extraFilterOne = FileSystems.getDefault().
                                 getPathMatcher(patterns[1]);
        }
        if (patterns.length > 2 && patterns[2] != null) {
            extraFilterTwo = FileSystems.getDefault().
                                 getPathMatcher(patterns[2]);
        }
 
        //Try with resources... so nice!
        try (DirectoryStream
 
                       ds =
                  Files.newDirectoryStream(dir, patterns[0])) {
            //iterate over the content of the directory and apply
            //any other extra pattern
            int count = 0;
            for (Path path : ds) {
                System.out.println(
                          'Evaluating ' + path.getFileName());
 
                if (extraFilterOne != null &&
                    extraFilterOne.matches(path.getFileName())) {
                    System.out.println(
                                  'Match found Do something!');
                }
 
                if (extraFilterTwo != null &&
                    extraFilterTwo.matches(path.getFileName())) {
                    System.out.println(
                             'Match found Do something else!');
                }
 
                count++;
            }
            System.out.println();
            System.out.printf(
                 '%d Files match the global pattern\n', count);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

Вы можете попробовать вызвать последний метод со следующими параметрами:

  • C: \ Images или / Images в зависимости от вашей ОС.
  • ? _ *. jpg Этот шаблон указывает, что вам нужны все изображения .jpg, имя которых начинается с одной цифры, за которой следует подчеркивание.
  • glob: 2_ * Указывает другой фильтр (с использованием синтаксиса glob), в котором вы хотите только элементы, имя которых начинается с цифры два, за которой следует подчеркивание.
  • glob: 3_ * Определяет другой фильтр (с использованием синтаксиса glob), в котором вы хотите только элементы, имя которых начинается с цифры три, за которой следует подчеркивание.

Наличие нескольких фильтров позволяет выполнять различные действия для соответствующих элементов.

Ниже приведен результат выполнения на моем компьютере с Windows:

И на моей виртуальной машине Linux:

Опять пиши один раз, беги везде! Однако обратите внимание, что порядок элементов зависит от системы, поэтому никогда не указывайте жестко положение файла или каталога.

Надеюсь, вам понравился этот пост, есть еще один более эффективный способ фильтрации содержимого каталога, и мы рассмотрим его в части 3. Нажмите здесь, чтобы загрузить исходный код.

Ссылка: Java 7: Фильтрация файлов с использованием NIO.2 — часть 2 от нашего партнера по JCG Алексиса Лопеса из блога Java и ME .