Javaでのパスの結合


99

Python私は2つのパスを結合することができますos.path.join

os.path.join("foo", "bar") # => "foo/bar"

私はそれOSUnixであるSolarisかどうか心配することなく、Javaで同じことを達成しようとしていますWindows

public static void main(String[] args) {
    Path currentRelativePath = Paths.get("");
    String current_dir = currentRelativePath.toAbsolutePath().toString();
    String filename = "data/foo.txt";
    Path filepath = currentRelativePath.resolve(filename);

    // "data/foo.txt"
    System.out.println(filepath);

}

それが作ることでPath.resolve( )私の現在のディレクトリに加わることを期待/home/user/testdata/foo.txtていました/home/user/test/data/foo.txt。何が問題になっていますか?


1
これは私には見られないものかもしれません。現在のパスは「」です。2番目のパスは「data / foo.txt」です。たぶん、あなたの問題は、あなたがするのではなく、Pathオブジェクトを印刷しているように見えるですfilepath.toString()
cjds

2
使用new File(parent, child)
saka1029

回答:


99

empty String作品を使用して現在のディレクトリを取得するための元のソリューションにもかかわらず。ただしuser.dir、現在のディレクトリとuser.homeホームディレクトリのプロパティを使用することをお勧めします。

Path currentPath = Paths.get(System.getProperty("user.dir"));
Path filePath = Paths.get(currentPath.toString(), "data", "foo.txt");
System.out.println(filePath.toString());

出力:

/Users/user/coding/data/foo.txt

Java Pathクラスのドキュメントから:

1つの名前要素のみで構成されるパスは、空のパスと見なされますemptyempty path is equivalent to accessing the default directoryファイルシステムのを使用してファイルにアクセスする。


なぜPaths.get("").toAbsolutePath()機能するのか

空の文字列がに渡されるPaths.get("")と、返されるPathオブジェクトには空のパスが含まれます。しかし、を呼び出すとPath.toAbsolutePath()、パスの長さがゼロより大きいかどうかを確認します。それ以外の場合は、user.dirシステムプロパティをて現在のパスを返します。

これは、Unixファイルシステム実装のコードです。UnixPath.toAbsolutePath()


基本的にPath、現在のディレクトリパスを解決したら、インスタンスを再度作成する必要があります。

またFile.separatorChar、プラットフォームに依存しないコードを使用することをお勧めします。

Path currentRelativePath = Paths.get("");
Path currentDir = currentRelativePath.toAbsolutePath(); // <-- Get the Path and use resolve on it.
String filename = "data" + File.separatorChar + "foo.txt";
Path filepath = currentDir.resolve(filename);

// "data/foo.txt"
System.out.println(filepath);

出力:

/Users/user/coding/data/foo.txt

私ではなく、ひょっとすると誰かが文字列で作業していると思って、separatorChar「より高いレベルの抽象化」よりも劣っていると思いますPathBuilder(currentRelativePath).append("data").append("foo.txt")
jingyu9575

22

Paths#get(String first, String... more) 州、

パス文字列、または結合したときにパス文字列を形成する文字列のシーケンスをに変換しますPath

...

Path表す空の最初の空でない文字列が含まれていない複数の空の文字列で、あればパスが返されます。

現在のユーザーディレクトリを取得するには、単にを使用しますSystem.getProperty("user.dir")

Path path = Paths.get(System.getProperty("user.dir"), "abc.txt");
System.out.println(path);

さらに、getメソッドはの可変長引数String使用します。これは、後続のパス文字列を提供するために使用されます。だから、作成するPathために/test/inside/abc.txtあなたは、以下の方法でそれを使用する必要があり、

Path path = Paths.get("/test", "inside", "abc.txt");

11

特定の方法ではありません。

Java 8以上を使用する場合、2つのオプションがあります。

a)java.util.StringJoinerを使用します

StringJoiner joiner = new StringJoiner(File.pathSeparator); //Separator
joiner.add("path1").add("path2");
String joinedString = joiner.toString();

b)使用 String.join(File.pathSeparator, "path1", "path2");

Java 7以下を使用している場合は、Apache commonsのcommons-langライブラリを使用できます。StringUtilsクラスには、セパレータを使用して文字列を結合するメソッドがあります。

c) StringUtils.join(new Object[] {"path1", "path2"}, File.pathSeparator);

補足:WindowsではLinuxのパス区切り文字「/」を使用できます(絶対パスは「/ C:/ mydir1 / mydir2」のようになることに注意してください。file://などのプロトコルを使用する場合は、常に「/」を使用すると非常に便利です。


StringJoinerが私を返した/home/user/test:foo.txt
cybertextron

あなたが知っているオプションは、存在する唯一のものではありません。たとえば、ジョイナーの代わりにStringBuilderを使用できます。実際、ファイルやパスではなく文字列に基づく実装は非常に単純であり、多くのシナリオで問題を引き起こします。
XenoRo

2
File.separator代わりに私のために働きましたFile.pathSeparator
Evan Siroky 2018年

Pathes.get( "path1"、 "path2")。toAbsolutePath()。toString()を使用してください
Erdinc Ay

5

最も基本的な方法は次のとおりです。

Path filepath = Paths.get("foo", "bar");

書いてはいけませんPaths.get("")。それがまったく機能することに驚いています。現在のディレクトリを明示的に参照する場合は、を使用しますPaths.get(System.getProperty("user.dir"))。ユーザーのホームディレクトリが必要な場合は、を使用しますPaths.get(System.getProperty("user.home"))

また、アプローチを組み合わせることができます。

Path filepath = Paths.get(
    System.getProperty("user.home"), "data", "foo.txt");

1

Javaでパスを結合するための最も信頼性が高く、プラットフォームに依存しない方法は、を使用することですPath::resolve(JavaDoc forに記載されていますPaths::get)。パスの一部を表す文字列の任意の長さの配列の場合、Javaストリームを使用してこれらを結合できます。

private static final String[] pieces = {
    System.getProperty("user.dir"),
    "data",
    "foo.txt"};
public static void main (String[] args) {
    Path dest = Arrays.stream(pieces).reduce(
    /* identity    */ Paths.get(""),
    /* accumulator */ Path::resolve,
    /* combiner    */ Path::resolve);
    System.out.println(dest);
}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.