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

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

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

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

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

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

Ответы

Ответ 1

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

Отпущенный способ - path.replaceAll("\\", "/").split("/").

Ответ 2

Литературные строки строк

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

Из API:

public static String quote(String s)

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

Параметры: 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, рассматриваемой как буквальная последовательность. Разрезы ('\') и знаки доллара ('$') не будут иметь особого значения.

Параметры: 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

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 может используется для аналогичной цели.

Ответ 4

Вы можете использовать интерфейс 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;
}

Ответ 5

Что насчет

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