web-dev-qa-db-ja.com

パスプラットフォームを独立して分割する方法は?

次のコードを使用して、指定されたパスからすべてのサブディレクトリを含む配列を取得しています。

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

特定のフォルダがこのパスの正しい場所にあるかどうかを確認するために配列が必要です。 findBugsがFile.separatorが正規表現として使用されていると文句を言うまで、これは良い解決策のように見えました。バックスラッシュがエスケープ文字であるため、Windowsファイル区切り文字をそこから正規表現を構築している関数に渡すことは悪い考えのようです。

File.separatorを使用せずに、クロスプラットフォームでパスを分割するにはどうすればよいですか?それとも、このようなコードは大丈夫ですか?

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

path.getParentFile()を繰り返し使用して、パスのすべてのコンポーネントを取得します。

推奨されない方法は、path.replaceAll("\\", "/").split("/")です。

14
akarnokd

パターン文字列の文字化

正規表現パターンとして使用するために任意の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内の文字のシーケンスと一致します。スラッシュ(_'\'_)とドル記号(_'$'_)には特別な意味はありません。

パラメータ: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"
_
39

空のリストを作成し、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()
_

Java Path および Paths ドキュメントページには他にも便利なメソッドがあります。

2
sabujp

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 も同様の目的で使用できます。

パスインターフェイスを使用できます。

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;
}
0
alniks