Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как разделить путь независимо от платформы?

Автор вопроса: JanuszОтветов: 6

Я использую следующий код, чтобы получить массив со всеми подкаталогами по заданному пути.

String[] subDirs = path.split(File.separator);

Мне нужен массив, чтобы проверить, находятся ли определенные папки в нужном месте на этом пути. Это выглядело как хорошее решение, пока findBugs не пожаловался, что File.separator используется как регулярное выражение. Кажется, что передача разделителя файлов Windows функции, которая строит из него регулярное выражение, является плохой идеей, потому что обратная косая черта является escape-символом.

Как я могу разделить путь кросс-платформенным способом без использования File.separator? Или такой код подойдет?

String[] subDirs = path.split("/");

javafilecross-platformregex

Ответы

Ответ 1 · рейтинг 16 · akarnokd

Используйте path.getParentFile() несколько раз, чтобы получить все компоненты пути.

Не рекомендуется использовать path.replaceAll("\\", "/").split("/").

Ответ 2 · рейтинг 41 · polygenelubricants

Литерализация строк шаблонов

Всякий раз, когда вам нужно буквально преобразовать произвольноеString в шаблон регулярного выражения, используйте Pattern.quote:

Из API:

public static String quote(String s)

Возвращает буквенный шаблон String для указанного String. Этот метод создает String, который можно использовать для создания Pattern, который будет соответствовать строке s, как если бы это был буквальный шаблон. Метасимволы или управляющие последовательности во входной последовательности не будут иметь специального значения.

Параметры: s - строка, которая должна быть литерализована
Возвращает: замена буквальной строки.

Это означает, что вы можете сделать следующее:

String[] subDirs = path.split(Pattern.quote(File.separator));

Буквенное замещение строк

Если вам нужно буквально преобразовать произвольную замену String, используйте Matcher.quoteReplacement.

Из API:

public static String quoteReplacement(String s)

Возвращает буквальную замену String для указанного String. Этот метод создает String, который будет работать как буквальная замена s в методе appendReplacement класса Matcher. Полученное String будет соответствовать последовательности символов в s, рассматриваемой как буквенная последовательность. Косая черта ('\') и знак доллара ('$') не будут иметь особого значения.

Эта цитируемая замена String также полезна в String.replaceFirst и String.replaceAll:

Обратите внимание, что обратная косая черта (\) и знаки доллара ($) в строке замены могут привести к тому, что результаты будут отличаться от результатов, если бы она рассматривалась как буквальная строка замены. Используйте Matcher.quoteReplacement для подавления специального значения этих символов, если это необходимо.


Примеры

    System.out.println(
        "O.M.G.".replaceAll(".", "!")
    ); // prints "!!!!!!"

    System.out.println(
        "O.M.G.".replaceAll(Pattern.quote("."), "!")
    ); // prints "O!M!G!"

    System.out.println(
        "Microsoft software".replaceAll("so", "$0")
    ); // prints "Microsoft software"

    System.out.println(
        "Microsoft software".replaceAll("so", Matcher.quoteReplacement("$0"))
    ); // prints "Micro$0ft $0ftware"

Ответ 3 · рейтинг 3 · sabujp

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

List<String> pathElements = new ArrayList<>();
Paths.get("/foo/bar/blah/baz").forEach(p -> pathElements.add(p.toString()))

Кроме того, если вам нужен определенный элемент пути, используйте:

<pathObject>.getName(<intIndex>).toString()

где <pathObject> возвращается вызовом Paths.get(), и если вам нужно несколько частей пути, возвращаемых в строке, используйте:

<pathObject>.subPath(<intStart>, <intEnd>).toString()

Вы можете получить общее количество элементов пути (для использования в <intEnd>) с помощью:

<pathObject>.getNameCount()

Существуют и другие полезные методы в Path и пути doc страницы.

Ответ 4 · рейтинг 2 · Marcus Junius Brutus

java.nio.file.Path реализует Iterable<Path>, поэтому вы можете сделать:

public static void showElements(Path p) {
    List<String> nameElements = new ArrayList<>();
    for (Path nameElement: p)
        nameElements.add(nameElement.toFile().getName());
    System.out.printf("For this file: [%s], the following elements were found: [%s]\n"
                      , p.toAbsolutePath()
                      , Joiner.on(", ").join(nameElements));
}

Методы getNameCount и getName может использоваться для аналогичной цели.

Ответ 5 · alniks

Вы можете использовать интерфейс Path:

Path p = Paths.get(pathStr);
for (int i = 0; i < p.getNameCount(); i++) {
    String name = p.getName(i).toString();
    //do what you need with name;
}

Ответ 6 · рейтинг -3 · Michael

Что о

String[] subDirs = path.split(File.separator.replaceAll("\\", "\\\\"));

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы