Existe-t-il un équivalent Java pour System.IO.Path.Combine()
C # /. NET? Ou tout code pour accomplir cela?
Cette méthode statique combine une ou plusieurs chaînes dans un chemin.
Existe-t-il un équivalent Java pour System.IO.Path.Combine()
C # /. NET? Ou tout code pour accomplir cela?
Cette méthode statique combine une ou plusieurs chaînes dans un chemin.
Réponses:
Plutôt que de tout garder basé sur des chaînes, vous devez utiliser une classe conçue pour représenter un chemin d'accès au système de fichiers.
Si vous utilisez Java 7 ou Java 8, vous devriez fortement envisager d'utiliser java.nio.file.Path
; Path.resolve
peut être utilisé pour combiner un chemin avec un autre ou avec une chaîne. La Paths
classe d'assistance est également utile. Par exemple:
Path path = Paths.get("foo", "bar", "baz.txt");
Si vous devez gérer des environnements pré-Java-7, vous pouvez utiliser java.io.File
, comme ceci:
File baseDirectory = new File("foo");
File subDirectory = new File(baseDirectory, "bar");
File fileInDirectory = new File(subDirectory, "baz.txt");
Si vous le souhaitez plus tard sous forme de chaîne, vous pouvez appeler getPath()
. En effet, si vous vouliez vraiment imiter Path.Combine
, vous pourriez simplement écrire quelque chose comme:
public static String combine(String path1, String path2)
{
File file1 = new File(path1);
File file2 = new File(file1, path2);
return file2.getPath();
}
path2
(en ignorant path1
) si path2
est un chemin absolu. La version Java supprimera le premier /
ou le \
traitera comme un chemin relatif.
File.getCanonicalPath
.
File
en C # si vous le souhaitez. (Je suppose que vous voulez dire que l'existence de File
est un avantage, avec lequel je suis d'accord.)
Dans Java 7, vous devez utiliser resolve
:
Path newPath = path.resolve(childPath);
Bien que la classe NIO2 Path puisse sembler un peu redondante pour File avec une API inutilement différente, elle est en fait subtilement plus élégante et robuste.
Notez que Paths.get()
(comme suggéré par quelqu'un d'autre) n'a pas de surcharge en prenant un Path
, et faire Paths.get(path.toString(), childPath)
n'est PAS la même chose que resolve()
. De la Paths.get()
documentation :
Notez que bien que cette méthode soit très pratique, son utilisation impliquera une référence supposée au système de fichiers par défaut et limitera l'utilité du code appelant. Par conséquent, il ne doit pas être utilisé dans le code de bibliothèque destiné à une réutilisation flexible. Une alternative plus flexible consiste à utiliser une instance Path existante comme ancre, telle que:
Path dir = ... Path path = dir.resolve("file");
La fonction sœur resolve
est l'excellente relativize
:
Path childPath = path.relativize(newPath);
La principale réponse est d'utiliser des objets File. Cependant Commons IO possède une classe FilenameUtils qui peut faire ce genre de chose, comme la méthode concat () .
Je sais que c'est longtemps depuis la réponse originale de Jon, mais j'avais une exigence similaire à celle de l'OP.
En étendant la solution de Jon, j'ai proposé ce qui suit, qui prendra un ou plusieurs segments de chemin prend autant de segments de chemin que vous pouvez lui lancer.
Usage
Path.combine("/Users/beardtwizzle/");
Path.combine("/", "Users", "beardtwizzle");
Path.combine(new String[] { "/", "Users", "beardtwizzle", "arrayUsage" });
Code ici pour les autres personnes ayant un problème similaire
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();
}
}
approche indépendante de la plate-forme (utilise File.separator, c'est-à-dire que will works dépend du système d'exploitation sur lequel le code s'exécute:
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
Pour améliorer la réponse de JodaStephen, Apache Commons IO a FilenameUtils qui le fait. Exemple (sous Linux):
assert org.apache.commons.io.FilenameUtils.concat("/home/bob", "work\\stuff.log") == "/home/bob/work/stuff.log"
Il est indépendant de la plate-forme et produira les séparateurs dont votre système a besoin.
Voici une solution qui gère plusieurs parties de chemin et conditions de bord:
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();
}
Si vous n'avez pas besoin de plus de chaînes, vous pouvez utiliser com.google.common.io.Files
Files.simplifyPath("some/prefix/with//extra///slashes" + "file//name")
obtenir
"some/prefix/with/extra/slashes/file/name"
Tard dans la soirée peut-être, mais je voulais partager mon point de vue à ce sujet. J'utilise un modèle Builder et autorise les append
appels chaînés de manière pratique . Il peut facilement être étendu pour prendre également en charge le travail avec des Path
objets.
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);
}
}
Exemple d'utilisation:
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();
Le résultat absolute
contiendra quelque chose comme:
/hello/world/warez.lha
ou peut-être même:
A:\hello\world\warez.lha
Cela fonctionne également en Java 8:
Path file = Paths.get("Some path");
file = Paths.get(file + "Some other path");
Cette solution offre une interface pour joindre des fragments de chemin à partir d'un tableau String []. Il utilise 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;
}
Ensuite, vous pouvez simplement faire:
String[] fragments = {"dir", "anotherDir/", "/filename.txt"};
String path = joinPaths(fragments);
Retour:
"/dir/anotherDir/filename.txt"