web-dev-qa-db-ja.com

Javaでパスを結合する方法は?

C#/。NETの System.IO.Path.Combine() に相当するJavaがありますか?または、これを達成するためのコードはありますか?

この静的メソッドは、1つ以上の文字列をパスに結合します。

308
novicer

すべてを文字列ベースにするのではなく、ファイルシステムパスを表すように設計されたクラスを使用する必要があります。

Java 7またはJava 8を使用している場合、 Java.nio.file.Path ;の使用を強く検討する必要があります。 Path.resolveを使用して、あるパスを別のパスまたは文字列と組み合わせることができます。 Paths ヘルパークラスも便利です。例えば:

Path path = Paths.get("foo", "bar", "baz.txt");

Java 7以前の環境に対応する必要がある場合は、次のように Java.io.File を使用できます。

File baseDirectory = new File("foo");
File subDirectory = new File(baseDirectory, "bar");
File fileInDirectory = new File(subDirectory, "baz.txt");

後で文字列として戻す場合は、getPath()を呼び出すことができます。実際、本当にPath.Combineを真似したければ、次のように書くことができます:

public static String combine(String path1, String path2)
{
    File file1 = new File(path1);
    File file2 = new File(file1, path2);
    return file2.getPath();
}
363
Jon Skeet

Java 7では、 resolve を使用する必要があります。

Path newPath = path.resolve(childPath);

NIO2 Pathクラスは、不必要に異なるAPIを使用するFileに対して少し冗長に見えるかもしれませんが、実際には微妙にエレガントで堅牢です。

Paths.get()(他の誰かが提案したように)にはPathをとるオーバーロードがなく、Paths.get(path.toString(), childPath)を行うことはresolve()と同じことではないことに注意してください。 Paths.get() docs から:

このメソッドは非常に便利ですが、これを使用すると、デフォルトのFileSystemへの参照が想定され、呼び出しコードのユーティリティが制限されることに注意してください。したがって、柔軟な再利用を目的としたライブラリコードでは使用しないでください。より柔軟な代替方法は、次のような既存のPathインスタンスをアンカーとして使用することです。

Path dir = ...
Path path = dir.resolve("file");

resolveの姉妹関数は、優れた relativize です。

Path childPath = path.relativize(newPath);
89

主な答えは、Fileオブジェクトを使用することです。ただし、 Commons IO にはクラスがあります- FilenameUtilsconcat() メソッドなど、この種のことを実行できます。

42
JodaStephen

ジョンの最初の答えから長い時間が経ちましたが、OPと同様の要件がありました。

Jonのソリューションを拡張する方法として、1つまたは複数のパスセグメントを取得する次の方法を思い付きました。

使用法

Path.combine("/Users/beardtwizzle/");
Path.combine("/", "Users", "beardtwizzle");
Path.combine(new String[] { "/", "Users", "beardtwizzle", "arrayUsage" });

同様の問題を持つ他の人のためにここにコードを書く

public class Path {
    public static String combine(String... paths)
    {
        File file = new File(paths[0]);

        for (int i = 1; i < paths.length ; i++) {
            file = new File(file, paths[i]);
        }

        return file.getPath();
    }
}
14
isNaN1247

JodaStephenの回答を強化するために、Apache Commons IOにはこれを行うFilenameUtilsがあります。例(Linuxの場合):

assert org.Apache.commons.io.FilenameUtils.concat("/home/bob", "work\\stuff.log") == "/home/bob/work/stuff.log"

プラットフォームに依存せず、システムに必要なセパレータを生成します。

11
alpian

プラットフォームに依存しないアプローチ(File.separatorを使用します。つまり、動作するのは、コードが実行されているオペレーティングシステムによって異なります。

Java.nio.file.Paths.get(".", "path", "to", "file.txt")
// relative unix path: ./path/to/file.txt
// relative windows path: .\path\to\filee.txt

Java.nio.file.Paths.get("/", "path", "to", "file.txt")
// absolute unix path: /path/to/filee.txt
// windows network drive path: \\path\to\file.txt

Java.nio.file.Paths.get("C:", "path", "to", "file.txt")
// absolute windows path: C:\path\to\file.txt
11

文字列以上必要ない場合は、 com.google.common.io.Files を使用できます。

Files.simplifyPath("some/prefix/with//extra///slashes" + "file//name")

取得するため

"some/prefix/with/extra/slashes/file/name"
2
Gismo Ranas

複数のパスパーツとエッジ条件を処理するソリューションを次に示します。

public static String combinePaths(String ... paths)
{
  if ( paths.length == 0)
  {
    return "";
  }

  File combined = new File(paths[0]);

  int i = 1;
  while ( i < paths.length)
  {
    combined = new File(combined, paths[i]);
    ++i;
  }

  return combined.getPath();
}
0
Bill

おそらくパーティーに遅れたが、私はこれについての私の意見を共有したかった。 Builderパターンを使用しており、append呼び出しを簡単にチェーンできます。 Pathオブジェクトの操作もサポートするように簡単に拡張できます。

public class Files  {
    public static class PathBuilder {
        private File file;

        private PathBuilder ( File root ) {
            file = root;
        }

        private PathBuilder ( String root ) {
            file = new File(root);
        }

        public PathBuilder append ( File more ) {
            file = new File(file, more.getPath()) );
            return this;
        }

        public PathBuilder append ( String more ) {
            file = new File(file, more);
            return this;
        }

        public File buildFile () {
            return file;
        }
    }

    public static PathBuilder buildPath ( File root ) {
        return new PathBuilder(root);
    }

    public static PathBuilder buildPath ( String root ) {
        return new PathBuilder(root);
    }
}

使用例:

File root = File.listRoots()[0];
String hello = "hello";
String world = "world";
String filename = "warez.lha"; 

File file = Files.buildPath(root).append(hello).append(world)
              .append(filename).buildFile();
String absolute = file.getAbsolutePath();

結果のabsoluteには次のようなものが含まれます。

/hello/world/warez.lha

または多分:

A:\hello\world\warez.lha
0

これはJava 8でも機能します:

Path file = Paths.get("Some path");
file = Paths.get(file + "Some other path");
0
rootExplorr