C#/。NETの System.IO.Path.Combine()
に相当するJavaがありますか?または、これを達成するためのコードはありますか?
この静的メソッドは、1つ以上の文字列をパスに結合します。
すべてを文字列ベースにするのではなく、ファイルシステムパスを表すように設計されたクラスを使用する必要があります。
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();
}
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);
主な答えは、Fileオブジェクトを使用することです。ただし、 Commons IO にはクラスがあります- FilenameUtilsconcat() メソッドなど、この種のことを実行できます。
ジョンの最初の答えから長い時間が経ちましたが、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();
}
}
JodaStephenの回答を強化するために、Apache Commons IOにはこれを行うFilenameUtilsがあります。例(Linuxの場合):
assert org.Apache.commons.io.FilenameUtils.concat("/home/bob", "work\\stuff.log") == "/home/bob/work/stuff.log"
プラットフォームに依存せず、システムに必要なセパレータを生成します。
プラットフォームに依存しないアプローチ(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
文字列以上必要ない場合は、 com.google.common.io.Files を使用できます。
Files.simplifyPath("some/prefix/with//extra///slashes" + "file//name")
取得するため
"some/prefix/with/extra/slashes/file/name"
複数のパスパーツとエッジ条件を処理するソリューションを次に示します。
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();
}
おそらくパーティーに遅れたが、私はこれについての私の意見を共有したかった。 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
これはJava 8でも機能します:
Path file = Paths.get("Some path");
file = Paths.get(file + "Some other path");