web-dev-qa-db-fra.com

Comment combiner des chemins en Java?

Existe-t-il un équivalent Java pour System.IO.Path.Combine() en C #/.NET? Ou n'importe quel code pour accomplir ceci?

Cette méthode statique combine une ou plusieurs chaînes dans un chemin.

291
novicer

Plutôt que de garder tout ce qui est basé sur des chaînes, vous devriez utiliser une classe conçue pour représenter un chemin de 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 classe Paths helper est également utile. Par exemple:

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

Si vous devez prendre en charge les environnements antérieurs à 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 souhaitez le récupérer ultérieurement sous forme de chaîne, vous pouvez appeler getPath(). En effet, si vous voulez vraiment imiter Path.Combine, vous pouvez 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();
}
354
Jon Skeet

En 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 légèrement plus élégante et robuste.

Notez que Paths.get() (comme suggéré par quelqu'un d'autre) n'a pas de surcharge prenant un Path, et que Paths.get(path.toString(), childPath) n'est PAS la même chose que resolve(). De la Paths.get() docs :

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 devrait pas être utilisé dans le code de bibliothèque conçu pour une réutilisation flexible. Une alternative plus flexible consiste à utiliser une instance de chemin existante comme ancre, telle que:

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

La fonction soeur de resolve est l'excellent relativize :

Path childPath = path.relativize(newPath);
80
Aleksandr Dubinsky

La réponse principale consiste à utiliser les objets File. Cependant Commons IO a une classe FilenameUtils qui peut faire ce genre de chose, telle que la méthode concat () .

41
JodaStephen

Je sais que cela fait longtemps depuis la réponse initiale de Jon, mais j'avais une exigence similaire à celle du PO. 

En prolongeant la solution de Jon, j'ai proposé ce qui suit: un ou plusieurs segments de chemin prennent autant de segments de chemin que vous pouvez lui envoyer.

Utilisation

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

Code ici pour les autres avec 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();
    }
}
14
isNaN1247

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"

Elle est indépendante de la plate-forme et produira les séparateurs dont votre système a besoin.

11
alpian

approche indépendante de la plateforme (utilise File.separator, c’est-à-dire que cela fonctionne dépend du système d’exploitation où le code est exécuté:

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
Maksim Kostromin

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"
2
Gismo Ranas

Cela fonctionne aussi dans Java 8:

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

Voici une solution qui gère plusieurs parties de chemin et plusieurs conditions Edge:

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

En retard à la fête peut-être, mais je voulais partager mon point de vue sur ceci. J'utilise un modèle de générateur et j'autorise des appels append chaînés de manière pratique. Il peut facilement être étendu pour prendre en charge le travail avec les objets 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);
    }
}

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();

La absolute résultante contiendra quelque chose comme:

/hello/world/warez.lha

ou peut-être même:

A:\hello\world\warez.lha
0
Stephan Henningsen