Gibt es ein Java-Äquivalent für System.IO.Path.Combine()
in C # /. NET? Oder irgendein Code, um dies zu erreichen?
Diese statische Methode kombiniert eine oder mehrere Zeichenfolgen zu einem Pfad.
Gibt es ein Java-Äquivalent für System.IO.Path.Combine()
in C # /. NET? Oder irgendein Code, um dies zu erreichen?
Diese statische Methode kombiniert eine oder mehrere Zeichenfolgen zu einem Pfad.
Antworten:
Anstatt alles stringbasiert zu halten, sollten Sie eine Klasse verwenden, die einen Dateisystempfad darstellt.
Wenn Sie Java 7 oder Java 8 verwenden, sollten Sie die Verwendung unbedingt in Betracht ziehen java.nio.file.Path
. Path.resolve
kann verwendet werden, um einen Pfad mit einem anderen oder mit einer Zeichenfolge zu kombinieren. Die Paths
Hilfsklasse ist auch nützlich. Zum Beispiel:
Path path = Paths.get("foo", "bar", "baz.txt");
Wenn Sie für Umgebungen vor Java-7 sorgen müssen, können Sie Folgendes verwenden java.io.File
:
File baseDirectory = new File("foo");
File subDirectory = new File(baseDirectory, "bar");
File fileInDirectory = new File(subDirectory, "baz.txt");
Wenn Sie es später als Zeichenfolge zurückhaben möchten, können Sie es aufrufen getPath()
. In der Tat, wenn Sie wirklich nachahmen wollten Path.Combine
, könnten Sie einfach etwas schreiben wie:
public static String combine(String path1, String path2)
{
File file1 = new File(path1);
File file2 = new File(file1, path2);
return file2.getPath();
}
path2
(ignoriert path1
), wenn path2
es sich um einen absoluten Pfad handelt. Die Java-Version löscht das führende /
oder \
und behandelt es als relativen Pfad.
File.getCanonicalPath
.
File
in C # erstellen, wenn Sie möchten. (Ich nehme an, Sie meinen, die Existenz von File
ist ein Vorteil, dem ich zustimmen würde.)
In Java 7 sollten Sie Folgendes verwenden resolve
:
Path newPath = path.resolve(childPath);
Während die NIO2 Path-Klasse für File mit einer unnötig anderen API etwas redundant erscheint, ist sie in der Tat subtil eleganter und robuster.
Beachten Sie, dass Paths.get()
(wie von jemand anderem vorgeschlagen) keine Überlastung auftritt Path
, und dass dies Paths.get(path.toString(), childPath)
NICHT dasselbe ist wie resolve()
. Aus den Paths.get()
Dokumenten :
Beachten Sie, dass diese Methode zwar sehr praktisch ist, ihre Verwendung jedoch einen angenommenen Verweis auf das Standard-Dateisystem impliziert und die Nützlichkeit des aufrufenden Codes einschränkt. Daher sollte es nicht in Bibliothekscode verwendet werden, der für eine flexible Wiederverwendung vorgesehen ist. Eine flexiblere Alternative besteht darin, eine vorhandene Pfadinstanz als Anker zu verwenden, z.
Path dir = ... Path path = dir.resolve("file");
Die Schwesterfunktion resolve
ist die ausgezeichnete relativize
:
Path childPath = path.relativize(newPath);
Die Hauptantwort ist die Verwendung von Dateiobjekten. Allerdings Commons IO hat eine Klasse FilenameUtils , die diese Art der Sache tun, wie die concat () Methode.
Ich weiß, dass es lange her ist, dass Jon ursprünglich geantwortet hat, aber ich hatte eine ähnliche Anforderung wie das OP.
Um Jons Lösung zu erweitern, habe ich Folgendes gefunden: Für ein oder mehrere Pfadsegmente werden so viele Pfadsegmente verwendet, wie Sie darauf werfen können.
Verwendungszweck
Path.combine("/Users/beardtwizzle/");
Path.combine("/", "Users", "beardtwizzle");
Path.combine(new String[] { "/", "Users", "beardtwizzle", "arrayUsage" });
Code hier für andere mit einem ähnlichen Problem
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();
}
}
Plattformunabhängiger Ansatz (verwendet File.separator, dh funktioniert funktioniert abhängig vom Betriebssystem, auf dem der Code ausgeführt wird:
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
Um die Antwort von JodaStephen zu verbessern, verfügt Apache Commons IO über FilenameUtils, das dies tut. Beispiel (unter Linux):
assert org.apache.commons.io.FilenameUtils.concat("/home/bob", "work\\stuff.log") == "/home/bob/work/stuff.log"
Es ist plattformunabhängig und produziert alle Separatoren, die Ihr System benötigt.
Hier ist eine Lösung, die mehrere Pfadteile und Randbedingungen behandelt:
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();
}
Wenn Sie nicht mehr als Zeichenfolgen benötigen, können Sie com.google.common.io.Files verwenden
Files.simplifyPath("some/prefix/with//extra///slashes" + "file//name")
bekommen
"some/prefix/with/extra/slashes/file/name"
Vielleicht zu spät zur Party, aber ich wollte meine Meinung dazu mitteilen. Ich verwende ein Builder-Muster und erlaube bequem verkettete append
Anrufe. Es kann leicht erweitert werden, um auch das Arbeiten mit Path
Objekten zu unterstützen .
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);
}
}
Anwendungsbeispiel:
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();
Das Ergebnis absolute
enthält Folgendes:
/hello/world/warez.lha
oder vielleicht sogar:
A:\hello\world\warez.lha
Dies funktioniert auch in Java 8:
Path file = Paths.get("Some path");
file = Paths.get(file + "Some other path");
Diese Lösung bietet eine Schnittstelle zum Verbinden von Pfadfragmenten aus einem String [] -Array. Es verwendet java.io.File.File (String parent, String child) :
public static joinPaths(String[] fragments) {
String emptyPath = "";
return buildPath(emptyPath, fragments);
}
private static buildPath(String path, String[] fragments) {
if (path == null || path.isEmpty()) {
path = "";
}
if (fragments == null || fragments.length == 0) {
return "";
}
int pathCurrentSize = path.split("/").length;
int fragmentsLen = fragments.length;
if (pathCurrentSize <= fragmentsLen) {
String newPath = new File(path, fragments[pathCurrentSize - 1]).toString();
path = buildPath(newPath, fragments);
}
return path;
}
Dann können Sie einfach tun:
String[] fragments = {"dir", "anotherDir/", "/filename.txt"};
String path = joinPaths(fragments);
Kehrt zurück:
"/dir/anotherDir/filename.txt"