След: Существенные Классы
Урок: Основной ввод-вывод
Раздел: Файловый ввод-вывод (Обладающий NIO.2)
Обнаружение Файлов
Домашняя страница > Существенные Классы > Основной ввод-вывод

Обнаружение Файлов

Если Вы когда-либо использовали сценарий оболочки, Вы наиболее вероятно использовали сопоставление с образцом, чтобы определить местоположение файлов. Фактически, Вы, вероятно, использовали это экстенсивно. Если Вы не использовали это, сопоставление с образцом использует специальные символы, чтобы создать образец, и затем имена файлов могут быть сравнены с тем образцом. Например, в большинстве сценариев оболочки, звездочке, *, соответствия любое число символов. Например, следующие списки команд все файлы в текущем каталоге тот конец в .html:

% ls *.html

java.nio.file пакет оказывает программируемую поддержку для этой полезной функции. Каждая реализация файловой системы обеспечивает a PathMatcher. Можно получить файловую систему PathMatcher при использовании getPathMatcher(String) метод в FileSystem class. Следующий фрагмент кода выбирает путь matcher для файловой системы значения по умолчанию:

String pattern = ...;
PathMatcher matcher =
    FileSystems.getDefault().getPathMatcher("glob:" + pattern);

Строковый параметр, к которому передают getPathMatcher определяет разновидность синтаксиса и образец, который будет соответствующим. Этот пример определяет синтаксис шарика. Если Вы незнакомы с синтаксисом шарика, см. то, Что является Шариком.

Синтаксис шарика удобен и гибок, но, если Вы предпочитаете, можно также использовать регулярные выражения, или regex, синтаксис. Для дополнительной информации о regex см. урок Регулярных выражений. Некоторые реализации файловой системы могли бы поддерживать другие синтаксисы.

Если Вы хотите использовать некоторую другую форму основанного на операция со строками сопоставления с образцом, можно создать свое собственное PathMatcher class. Примеры в этой странице используют синтаксис шарика.

Как только Вы создали Ваш PathMatcher экземпляр, Вы готовы соответствовать файлы против этого. PathMatcher у интерфейса есть единственный метод, matches, это берет a Path параметр и возвраты булево: Это или соответствует образец, или это не делает. Следующий фрагмент кода ищет файлы тот конец в .java или .class и печатные издания те файлы к стандартному выводу:

PathMatcher matcher =
    FileSystems.getDefault().getPathMatcher("glob:*.{java,class}");

Path filename = ...;
if (matcher.matches(filename)) {
    System.out.println(filename);
}

Рекурсивное Сопоставление с образцом

Поиск файлов, которые соответствуют определенный образец, идет взявшись за руки с обходом дерева файла. Сколько времен Вы знаете, что файл находится где-нибудь на файловой системе, но где? Или возможно Вы должны найти все файлы в дереве файла, у которых есть определенное расширение файла.

Find пример делает точно это. Find подобно UNIX find утилита, но срезал функционально. Можно расширить этот пример, чтобы включать другую функциональность. Например, find утилита поддерживает -prune флаг, чтобы исключить все поддерево из поиска. Вы могли реализовать ту функциональность, возвращаясь SKIP_SUBTREE в preVisitDirectory метод. Реализовывать -L опция, которая следует за символьными ссылками, Вы могли использовать с четырьмя параметрами walkFileTree метод и передача в FOLLOW_LINKS перечисление (но удостоверяются, что Вы тестируете на круговые ссылки в visitFile метод).

Чтобы запустить приложение Находки, используйте следующий формат:

% java Find <path> -name "<glob_pattern>"

Образец помещается в кавычках, таким образом, любые подстановочные знаки не интерпретируются оболочкой. Например:

% java Find . -name "*.html"

Вот исходный код для Find пример:

/**
 * Sample code that finds files that match the specified glob pattern.
 * For more information on what constitutes a glob pattern, see
 * http://docs.oracle.com/javase/tutorial/essential/io/fileOps.html#glob
 *
 * The file or directories that match the pattern are printed to
 * standard out.  The number of matches is also printed.
 *
 * When executing this application, you must put the glob pattern
 * in quotes, so the shell will not expand any wild cards:
 *              java Find . -name "*.java"
 */

import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import static java.nio.file.FileVisitResult.*;
import static java.nio.file.FileVisitOption.*;
import java.util.*;


public class Find {

    public static class Finder
        extends SimpleFileVisitor<Path> {

        private final PathMatcher matcher;
        private int numMatches = 0;

        Finder(String pattern) {
            matcher =
                FileSystems.getDefault()
                    .getPathMatcher("glob:" + pattern);
        }

        // Compares the glob pattern against
        // the file or directory name.
        void find(Path file) {
            Path name = file.getFileName();
            if (name != null && matcher.matches(name)) {
                numMatches++;
                System.out.println(file);
            }
        }

        // Prints the total number of
        // matches to standard out.
        void done() {
            System.out.println("Matched: "
                + numMatches);
        }

        // Invoke the pattern matching
        // method on each file.
        @Override
        public FileVisitResult
            visitFile(Path file,
                BasicFileAttributes attrs) {
            find(file);
            return CONTINUE;
        }

        // Invoke the pattern matching
        // method on each directory.
        @Override
        public FileVisitResult
            preVisitDirectory(Path dir,
                BasicFileAttributes attrs) {
            find(dir);
            return CONTINUE;
        }

        @Override
        public FileVisitResult
            visitFileFailed(Path file,
                IOException exc) {
            System.err.println(exc);
            return CONTINUE;
        }
    }

    static void usage() {
        System.err.println("java Find <path>" +
            " -name \"<glob_pattern>\"");
        System.exit(-1);
    }

    public static void main(String[] args)
        throws IOException {

        if (args.length < 3 
            || !args[1].equals("-name"))
            usage();

        Path startingDir = Paths.get(args[0]);
        String pattern = args[2];

        Finder finder = new Finder(pattern);
        Files.walkFileTree(startingDir, finder);
        finder.done();
    }
}

Рекурсивно обход дерева файла покрывается Обходом Дерева Файла.


Проблемы с примерами? Попытайтесь Компилировать и Выполнить Примеры: FAQ.
Жалобы? Поздравление? Предложения? Дайте нам свою обратную связь.

Предыдущая страница: Обход Дерева Файла
Следующая страница: Наблюдение Каталога для Изменений



Spec-Zone.ru - all specs in one place