Jak podzielić niezależną platformę ścieżki?

Używam poniższego kodu, aby uzyskać tablicę ze wszystkimi podkatalogami z danej ścieżki.

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

Potrzebuję tablicy, aby sprawdzić, czy określone foldery znajdują się we właściwym miejscu w tej ścieżce. Wyglądało to na dobre rozwiązanie, dopóki findBugs nie narzekał, że File.separator jest używany jako wyrażenie regularne. Wydaje się, że przekazanie separatora plików systemu Windows do funkcji budującej z niego wyrażenie regularne jest złym pomysłem, ponieważ ukośnik odwrotny jest znakiem ucieczki.

Jak mogę podzielić ścieżkę na wiele platform bez użycia File.separator? A może taki kod jest w porządku?

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

person Janusz    schedule 08.07.2009    source źródło


Odpowiedzi (6)


Użyj path.getParentFile() wielokrotnie, aby uzyskać wszystkie składniki ścieżki.

Zniechęcony sposób to path.replaceAll("\\", "/").split("/").

person akarnokd    schedule 08.07.2009
comment
+1 istnieją hackerskie sposoby, aby to zrobić i napisz, jak to zrobić. to właściwy sposób, który pozwoli Ci zaoszczędzić wiele bólu w porównaniu z dzieleniem za pomocą „/”, „\”, ‹znaku wstawki dla systemu operacyjnego, o którym tutaj całkowicie zapomniałeś› - person ShuggyCoUk; 08.07.2009
comment
Tak, uderzyłem w zniechęcony sposób. Przepraszam. - person akarnokd; 08.07.2009

Literalizowanie ciągów wzorców

Ilekroć musisz literalizować dowolnyString, który ma zostać użyty jako wzorzec wyrażenia regularnego, użyj Pattern.quote:

Z API:

public static String quote(String s)

Zwraca wzorzec literału String dla określonego String. Ta metoda generuje String, którego można użyć do utworzenia Pattern, który pasowałby do ciągu s tak, jakby był to dosłowny wzorzec. Metaznaki lub sekwencje specjalne w sekwencji wejściowej nie będą miały specjalnego znaczenia.

Parametry: s – ciąg znaków, który ma zostać dosłowny
Zwroty: Dosłowna zamiana ciągu

Oznacza to, że możesz wykonać następujące czynności:

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

Literalizowanie ciągów zastępczych

Jeśli chcesz dosłownie zinterpretować dowolną zamianę String, użyj Matcher.quoteReplacement.

Z API:

public static String quoteReplacement(String s)

Zwraca dosłowny zamiennik String dla określonego String. Ta metoda generuje String, który będzie działał jako dosłowny zamiennik s w metodzie appendReplacement klasy Matcher. Wygenerowane String będzie pasować do sekwencji znaków w s traktowanych jako sekwencja dosłowna. Ukośniki ('\') i znaki dolara ('$') nie będą miały specjalnego znaczenia.

Parametry: s - ciąg znaków, który ma zostać dosłowny
Zwroty: Dosłowna zamiana ciągu

Ten cytowany zamiennik String jest również przydatny w String.replaceFirst i String.replaceAll:

Należy pamiętać, że ukośniki odwrotne (\) i znaki dolara ($) w ciągu zastępującym mogą spowodować, że wyniki będą inne niż w przypadku traktowania go jako dosłownego ciągu zastępującego. W razie potrzeby użyj Matcher.quoteReplacement, aby ukryć specjalne znaczenie tych znaków.


Przykłady

    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"
person polygenelubricants    schedule 29.04.2010

Utwórz pustą listę i użyj forEach do iteracji po elementach ścieżki, wstawiając każdy z nich do listy do późniejszego wykorzystania:

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

Ponadto, jeśli potrzebujesz określonego elementu ścieżki, użyj:

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

gdzie <pathObject> jest zwracane przez wywołanie Paths.get(), a jeśli potrzebujesz wielu części ścieżki zwróconych w ciągu znaków, użyj:

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

Możesz uzyskać całkowitą liczbę elementów ścieżki (do użycia w <intEnd>) za pomocą:

<pathObject>.getNameCount()

Istnieją inne przydatne metody w Ścieżka i Ścieżki dok strony.

person sabujp    schedule 08.06.2018
comment
Dodaj wyjaśnienie, dlaczego Twój kod działa i jak rozwiązuje problemy wymienione w pytaniu - person Gergely Toth; 08.06.2018
comment
Jeśli daje rozwiązanie, proszę o wyjaśnienie, w przeciwnym razie odpowiedź zostanie usunięta. - person Ashish Ratan; 08.06.2018

java.nio.file.Path implementuje Iterable<Path>, dzięki czemu możesz:

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));
}

Metody getNameCount i getName może być używane w podobnym celu.

person Marcus Junius Brutus    schedule 08.03.2016

Możesz użyć interfejsu 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;
}
person alniks    schedule 23.12.2016

Co powiesz na

String[] subDirs = path.split(File.separator.replaceAll("\\", "\\\\"));
person Michael    schedule 08.07.2009
comment
Pytanie dotyczy wielu platform, Twoje działa tylko w systemie Windows. - person kaiser; 17.02.2021