Comment obtenir le répertoire de travail actuel en Java?

1029

Je veux accéder à mon répertoire de travail actuel en utilisant java.

Mon code:

 String current = new java.io.File( "." ).getCanonicalPath();
        System.out.println("Current dir:"+current);
 String currentDir = System.getProperty("user.dir");
        System.out.println("Current dir using System:" +currentDir);

Production:

Current dir: C:\WINDOWS\system32
Current dir using System: C:\WINDOWS\system32

Ma sortie n'est pas correcte car le lecteur C n'est pas mon répertoire actuel.

Comment obtenir le répertoire courant?

Qazi
la source
2
pouvez-vous coller ici ce que vous voyez lorsque vous exécutez la cdcommande sur votre invite de commande lorsque vous l'exécutez?
Nishant
3
Qu'est-ce que vous essayez d'accomplir en accédant au répertoire de travail? Pourrait-il être fait en utilisant le chemin de classe à la place? Par exemple, si vous devez lire un fichier texte sur le système de fichiers, vous pouvez le trouver facilement lorsqu'il se trouve sur le chemin de classe.
earldouglas
1
Comment? Pourriez-vous élaborer, s'il vous plaît?
C graphics
1
Pour plus d'informations sur l'accès à un fichier sur le chemin de classe, voir stackoverflow.com/questions/1464291/…
downeyt
7
À des fins de débogage, le répertoire de travail peut être utile pour savoir si le programme ne semble pas pouvoir accéder aux fichiers existants.
nsandersen

Réponses:

1152
public class JavaApplication {
  public static void main(String[] args) {
       System.out.println("Working Directory = " + System.getProperty("user.dir"));
  }
}

Cela imprimera un chemin absolu complet à partir duquel votre application a été initialisée.


De la documentation :

java.iole package résout les chemins d'accès relatifs à l'aide du répertoire utilisateur actuel. Le répertoire actuel est représenté comme une propriété système, c'est-à-dire, user.diret est le répertoire à partir duquel la JVM a été invoquée.

Anuj Patel
la source
25
@ubuntudroid: c'est pourquoi j'ai mentionné spécifiquement qu'il imprimera le chemin à partir duquel l'application a été initialisée. Je suppose que le démarreur de thread exécute directement le fichier jar / programme après avoir lancé l'invite de commande (qui se trouve essentiellement dans C: \ WINDOWS \ system32). J'espère que vous comprenez mon point. En supposant que vous ayez voté, appréciez qu'au moins vous vouliez laisser une réponse. :)
Anuj Patel
1
user.dir obtiendra le chemin d'accès au dossier dans lequel le processus a été lancé. Pour obtenir le chemin réel vers le dossier principal de l'application, voir ma réponse ci-dessous.
Peter De Winter
1
Je veux dire "tout le code qui s'y fonde pour trouver le répertoire courant échoue.". Pas tout le code en général. (Je devais ralentir pour éditer le commentaire original)
SubOptimal
13
@SubOptimal si l'utilisateur a défini -Duser.dir, il est prêt à l'exécuter dans un répertoire de travail personnalisé.
barwnikk
5
@indyaah en effet cette réponse est fausse, il y a une différence subtile entre un répertoire de travail utilisateur et un répertoire de travail courant d'un processus système (cwd); la plupart du temps, "user.dir" pointe vers le cwd d'un processus (java); mais "user.dir" a une sémantique différente et ne doit pas être utilisé pour obtenir le cwd d'un processus java; btw: il y a plus de propriétés disponibles pour le processus java docs.oracle.com/javase/tutorial/essential/environment/… juste pour référence
comeGetSome
382

Voir: http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html

En utilisant java.nio.file.Pathet java.nio.file.Paths, vous pouvez faire ce qui suit pour montrer ce que Java pense être votre chemin actuel. Ceci pour 7 et plus, et utilise NIO.

Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
System.out.println("Current relative path is: " + s);

Cela génère Current relative path is: /Users/george/NetBeansProjects/Tutorialsque dans mon cas, j'ai exécuté la classe. La construction de chemins d'une manière relative, en n'utilisant pas de séparateur de tête pour indiquer que vous construisez un chemin absolu, utilisera ce chemin relatif comme point de départ.

geoO
la source
2
Le premier n'a pas été vérifié, mais le second récupérera votre dossier personnel. Pas le répertoire de travail actuel dans lequel l'application s'exécute.
Peter De Winter
12
Veuillez ne pas confondre le répertoire personnel de l'utilisateur ("user.home", / Users / george dans votre cas) et le répertoire de travail actuel ("user.dir", qui sera le répertoire à partir duquel vous avez démarré la JVM pour votre application , pourrait donc être quelque chose comme par exemple / Users / george / workspace / FooBarProject).
David
1
Je préfère cette façon. Quand j'ai besoin du parent du répertoire de travail, ça ne marche pas :, Paths.get("").getParent()ça donne null. Au lieu de cela cela fonctionne: Paths.get("").toAbsolutePath().getParent().
Ole VV
235

Les travaux suivants sur Java 7 et plus (voir ici pour la documentation).

import java.nio.file.Paths;

Paths.get(".").toAbsolutePath().normalize().toString();
Dmitry Bespalov
la source
11
Comment est-ce mieux que le plus portable import java.io.File; File(".").getAbsolutePath()?
Evgeni Sergeev
8
Quand vous dites portable, vous voulez dire que cela fonctionne dans Java 6 et versions antérieures? Paths.get()peut être considérée comme meilleure en ce qu'elle donne un accès direct à l' Pathinterface plus puissante .
Ole VV
8
Quel est l'avantage potentiel d'utiliser .normalize()dans ce contexte?
Ole VV
7
@ OleV.V. De Javadoc: ( méthode de normalisation )Returns a path that is this path with redundant name elements eliminated.
Stephan
Serait déjà normalisé dans ce cas.
JM Becker
73

Cela vous donnera le chemin de votre répertoire de travail actuel:

Path path = FileSystems.getDefault().getPath(".");

Et cela vous donnera le chemin vers un fichier appelé "Foo.txt" dans le répertoire de travail:

Path path = FileSystems.getDefault().getPath("Foo.txt");

Edit: Pour obtenir un chemin absolu du répertoire courant:

Path path = FileSystems.getDefault().getPath(".").toAbsolutePath();

* Mise à jour * Pour obtenir le répertoire de travail actuel:

Path path = FileSystems.getDefault().getPath("").toAbsolutePath();
marque
la source
11
cela renvoie juste '.' pour moi.
john ktejik
3
Oui, dans de nombreux systèmes, ce sera la référence au répertoire de travail. Pour obtenir le chemin absolu, vous pouvez ajouter un autre appel de méthodePath path = FileSystems.getDefault().getPath(".").toAbsolutePath();
Mark
2
Vous n'avez pas besoin du foo.txt, mettez simplement une chaîne vide pour obtenir le répertoire
john ktejik
1
Sous Windows (10), cela me donne juste un Pathobjet pointant vers un fichier appelé .à l'intérieur du répertoire de travail actuel. Utiliser une chaîne vide, plutôt que de "."travailler pour moi.
Kröw
36

C'est la solution pour moi

File currentDir = new File("");
user2430452
la source
1
Cela a des effets secondaires lorsque vous utilisez un tel objet File en tant que parent d'un autre fichier: nouveau fichier (nouveau fichier (""), "subdir") ne fonctionnera pas comme prévu
MRalwasser
13
Pour résoudre ce problème, utilisez new File("").getAbsoluteFile()plutôt.
MRalwasser
4
Pour ce que ça vaut, j'ai eu plus de chance avec File (".").
keshlam
Comment définir un chemin relatif en Java Cette page m'a aidé. J'ai également supposé que je devrais utiliser /lors de la création d'un chemin relatif. J'avais tort, ne commence pas /. ../fonctionne également pour monter dans l'arborescence des répertoires.
Irrationalkilla
@keshlam Cela m'a donné un fichier dans le répertoire courant appelé ..
Kröw
32

J'ai trouvé cette solution dans les commentaires qui est meilleure que les autres et plus portable:

String cwd = new File("").getAbsolutePath();

Ou même

String cwd = Paths.get("").toAbsolutePath();
Liberté
la source
C'est exactement la même chose que la réponse de comeGetSome et c'est en fait la voie Java <7
GoGoris
30

Qu'est-ce qui vous fait penser que c: \ windows \ system32 n'est pas votre répertoire actuel? leuser.dir propriété doit être explicitement le "répertoire de travail actuel de l'utilisateur".

Autrement dit, sauf si vous démarrez Java à partir de la ligne de commande, c: \ windows \ system32 est probablement votre CWD. Autrement dit, si vous double-cliquez pour démarrer votre programme, il est peu probable que le CWD soit le répertoire à partir duquel vous double-cliquez.

Edit : Il semble que cela ne soit vrai que pour les anciennes fenêtres et / ou versions Java.

Paul Wagland
la source
2
Cela ne semble pas être vrai, du moins pas sur ma machine Windows 7 utilisant Java 7. user.direst toujours le dossier où j'ai double-cliqué sur le fichier jar.
Jolta
26

Utilisation CodeSource#getLocation() .

Cela fonctionne également très bien dans les fichiers JAR. Vous pouvez obtenir CodeSourcepar ProtectionDomain#getCodeSource()et le ProtectionDomaintour peut être obtenu par Class#getProtectionDomain().

public class Test {
    public static void main(String... args) throws Exception {
        URL location = Test.class.getProtectionDomain().getCodeSource().getLocation();
        System.out.println(location.getFile());
    }
}
Bigoloo
la source
2
Cela renvoie l'emplacement du fichier JAR. Pas ce qui était demandé.
Marquis de Lorne
22
this.getClass().getClassLoader().getResource("").getPath()
Peter De Winter
la source
12
Lance un NPE lorsque je lance mon application à partir d'un fichier JAR en double-cliquant dessus.
Matthew Wise
2
Cela renvoie ""si l'application s'exécute à partir d'un fichier JAR ou d'un élément CLASSPATH. Pas ce qui était demandé.
Marquis de Lorne
@ Zizouz212 getClass()est une méthode objet, donc dans un contexte statique, la simple suppression de thisne fonctionne pas. Vous devez vous référer explicitement à la classe dans laquelle vous vous trouvez MyClass.class.getClassLoader()......
Kröw
Néanmoins, il ne retournera pas le répertoire de travail ...
Angel O'Sphere
18

généralement, en tant qu'objet File:

File getCwd() {
  return new File("").getAbsoluteFile();
}

vous voudrez peut-être avoir une chaîne complète comme "D: / a / b / c":

getCwd().getAbsolutePath()
viens en chercher
la source
1
Cela fonctionne bien dans les tests Android car Android n'inclut pas java.nio.file.Files.
iamreptar
Ne semble pas fonctionner pour moi dans un contexte statique (nouveau fichier ("") lève NullPointerException) ..?
nsandersen
2
@nsandersen vous avez probablement utilisé un mauvais objet File: System.out.println (new java.io.File (""). getAbsolutePath ());
comeGetSome
5

Sous Linux, lorsque vous exécutez un fichier jar à partir du terminal , ces deux paramètres renverront le même String: "/ home / CurrentUser" , peu importe où se trouve votre fichier jar. Cela dépend uniquement du répertoire courant que vous utilisez avec votre terminal, lorsque vous démarrez le fichier jar.

Paths.get("").toAbsolutePath().toString();

System.getProperty("user.dir");

Si votre Classavec mainest appelé MainClass, essayez:

MainClass.class.getProtectionDomain().getCodeSource().getLocation().getFile();

Cela renverra un Stringavec chemin absolu du pot fichier.

Jan Povolný
la source
3
Ce qui n'est pas ce qui a été demandé.
Marquis de Lorne
5

L'utilisation de Windows user.dir renvoie le répertoire comme prévu, mais PAS lorsque vous démarrez votre application avec des droits élevés (exécuté en tant qu'administrateur), dans ce cas, vous obtenez C: \ WINDOWS \ system32

SijeDeHaan
la source
3

J'espère que vous souhaitez accéder au répertoire actuel, y compris le package, c'est-à-dire si votre programme Java est dans c:\myApp\com\foo\src\service\MyTest.javaet que vous souhaitez imprimer jusque- c:\myApp\com\foo\src\servicelà, vous pouvez essayer le code suivant:

String myCurrentDir = System.getProperty("user.dir")
            + File.separator
            + System.getProperty("sun.java.command")
                    .substring(0, System.getProperty("sun.java.command").lastIndexOf("."))
                    .replace(".", File.separator);
    System.out.println(myCurrentDir);

Remarque: Ce code n'est testé que sous Windows avec Oracle JRE.

JSS
la source
6
Il serait injuste de ne pas dévaloriser cette réponse. Veuillez réfléchir plus attentivement avant de poster. Votre code est cassé, sauf si toutes ces conditions sont vraies: 1. le JRE est celui d'Oracle, sinon il n'y aura pas de propriété système "sun.java.command" → NPE; 2. le système d'exploitation est Windows (utilisez File.separatorplutôt, ou un Fileconstructeur multi-arguments ); 3. le chemin d'accès aux classes est spécifié sur la ligne de commande et le «répertoire en cours incluant le package» (??) est: a. spécifié en premier, b. spécifié absolument, c. correspond exactement à la CWD (même avec l'insensibilité à la casse de Windows), et d. est un descendant de la CWD
Michael Scheper
Cela concerne les points 1 et 2. Mais à moins que je manque quelque chose, vous comptez toujours sur le chemin de classe spécifié dans la ligne de commande (c'est-à-dire pas dans une variable d'environnement), et pour le «répertoire actuel, y compris le package» (I admettez que je ne comprends pas vraiment ce que vous entendez par là) étant un descendant du premier élément du chemin de classe. Et le problème de correspondance de cas reste. Je suis désolé si mon commentaire n'a pas été utile; J'ai sacrifié la clarté pour rester dans la limite du nombre de commentaires.
Michael Scheper
@Inversus, il "ne fonctionne parfaitement" que dans certains environnements; vous avez juste eu la chance de le tester dans l'un d'eux. L'écriture de logiciels qui échouent dans des environnements d'exécution légitimes n'est pas une bonne pratique, même lorsque votre ensemble d'environnements de test n'est pas suffisamment étendu pour les inclure.
Charles Duffy
@CharlesDuffy Vous avez raison, ce n'est pas une bonne pratique. Heureusement, cette solution «résolvant mon problème spécifique» ne l'a pas fait «[échouer] dans des environnements d'exécution légitimes». En fait, cela m'a aidé à résoudre un tel échec et à écrire du code plus robuste, en plus de résoudre le problème très spécifique que j'avais (qui n'était que quelque peu lié à cette question / réponse). Je suppose que j'ai eu la chance de le trouver.
Inversus
3

Mentionnez qu'il est enregistré uniquement Windowsmais je pense que cela fonctionne parfaitement sur d'autres systèmes d'exploitation [ Linux,MacOs,Solaris] :).


J'avais 2 .jar fichiers dans le même répertoire. Je voulais à partir d'un .jarfichier pour démarrer l'autre .jarfichier qui se trouve dans le même répertoire.

Le problème est que lorsque vous le démarrez à partir du cmdrépertoire en cours, c'est system32.


Avertissements!

  • Ce qui suit semble fonctionner assez bien dans tous les tests que j'ai faits, même avec le nom du dossier ;][[;'57f2g34g87-8+9-09!2#@!$%^^&()ou()%&$%^@# cela fonctionne bien.
  • J'utilise le ProcessBuilderavec le ci-dessous comme suit:

🍂 ..

//The class from which i called this was the class `Main`
String path = getBasePathForClass(Main.class);
String applicationPath=  new File(path + "application.jar").getAbsolutePath();


System.out.println("Directory Path is : "+applicationPath);

//Your know try catch here
//Mention that sometimes it doesn't work for example with folder `;][[;'57f2g34g87-8+9-09!2#@!$%^^&()` 
ProcessBuilder builder = new ProcessBuilder("java", "-jar", applicationPath);
builder.redirectErrorStream(true);
Process process = builder.start();

//...code

🍂 getBasePathForClass(Class<?> classs):

    /**
     * Returns the absolute path of the current directory in which the given
     * class
     * file is.
     * 
     * @param classs
     * @return The absolute path of the current directory in which the class
     *         file is.
     * @author GOXR3PLUS[StackOverFlow user] + bachden [StackOverFlow user]
     */
    public static final String getBasePathForClass(Class<?> classs) {

        // Local variables
        File file;
        String basePath = "";
        boolean failed = false;

        // Let's give a first try
        try {
            file = new File(classs.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());

            if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
                basePath = file.getParent();
            } else {
                basePath = file.getPath();
            }
        } catch (URISyntaxException ex) {
            failed = true;
            Logger.getLogger(classs.getName()).log(Level.WARNING,
                    "Cannot firgue out base path for class with way (1): ", ex);
        }

        // The above failed?
        if (failed) {
            try {
                file = new File(classs.getClassLoader().getResource("").toURI().getPath());
                basePath = file.getAbsolutePath();

                // the below is for testing purposes...
                // starts with File.separator?
                // String l = local.replaceFirst("[" + File.separator +
                // "/\\\\]", "")
            } catch (URISyntaxException ex) {
                Logger.getLogger(classs.getName()).log(Level.WARNING,
                        "Cannot firgue out base path for class with way (2): ", ex);
            }
        }

        // fix to run inside eclipse
        if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
                || basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
            basePath = basePath.substring(0, basePath.length() - 4);
        }
        // fix to run inside netbeans
        if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
            basePath = basePath.substring(0, basePath.length() - 14);
        }
        // end fix
        if (!basePath.endsWith(File.separator)) {
            basePath = basePath + File.separator;
        }
        return basePath;
    }
GOXR3PLUS
la source
Cela renvoie l'emplacement du fichier JAR. Pas ce qui était demandé.
Marquis de Lorne
@EJP L'emplacement du fichier .jar n'est pas le répertoire de travail actuel du programme java?
GOXR3PLUS
2

Le répertoire de travail actuel est défini différemment dans différentes implémentations Java. Pour certaines versions antérieures à Java 7, il n'existait aucun moyen cohérent d'obtenir le répertoire de travail. Vous pouvez contourner cela en lançant un fichier Java avec -Det en définissant une variable pour contenir les informations

Quelque chose comme

java -D com.mycompany.workingDir="%0"

Ce n'est pas tout à fait vrai, mais vous voyez l'idée. Alors System.getProperty("com.mycompany.workingDir")...

MJB
la source
6
Pas pertinent pour la question.
Peter De Winter
1
Il a une signification pour Java - c'est l'emplacement sur le disque où les fichiers que vous ouvrez avec des chemins d'accès relatifs sont relatifs.
Rob I
2
Oui, cela a un sens. Mes mots ont été quelque peu mal choisis. Mais vous manquez le point - avant Java 7, il n'y avait aucun moyen de connaître le répertoire de travail actuel, et différentes implémentations les définissaient ... différemment ...
MJB
1

supposons que vous essayez d'exécuter votre projet dans eclipse, ou netbean ou autonome à partir de la ligne de commande. J'ai écrit une méthode pour y remédier

public static final String getBasePathForClass(Class<?> clazz) {
    File file;
    try {
        String basePath = null;
        file = new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
        if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
            basePath = file.getParent();
        } else {
            basePath = file.getPath();
        }
        // fix to run inside eclipse
        if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
                || basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
            basePath = basePath.substring(0, basePath.length() - 4);
        }
        // fix to run inside netbean
        if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
            basePath = basePath.substring(0, basePath.length() - 14);
        }
        // end fix
        if (!basePath.endsWith(File.separator)) {
            basePath = basePath + File.separator;
        }
        return basePath;
    } catch (URISyntaxException e) {
        throw new RuntimeException("Cannot firgue out base path for class: " + clazz.getName());
    }
}

Pour l'utiliser, partout où vous voulez obtenir le chemin de base pour lire le fichier, vous pouvez passer votre classe d'ancrage à la méthode ci-dessus, le résultat peut être la chose dont vous avez besoin: D

Meilleur,

Bachden
la source
2
Cela renvoie l'emplacement du fichier JAR. Pas ce qui était demandé.
Marquis de Lorne
@ user207421 oui je sais que cette réponse n'est pas la vraie réponse à la question, mais la plupart du temps, tout le monde veut obtenir le "répertoire où se trouvent les pots" au lieu de "répertoire de travail en ligne de commande".
bachden
0

Aucune des réponses publiées ici n'a fonctionné pour moi. Voici ce qui a fonctionné:

java.nio.file.Paths.get(
  getClass().getProtectionDomain().getCodeSource().getLocation().toURI()
);

Edit: La version finale de mon code:

URL myURL = getClass().getProtectionDomain().getCodeSource().getLocation();
java.net.URI myURI = null;
try {
    myURI = myURL.toURI();
} catch (URISyntaxException e1) 
{}
return java.nio.file.Paths.get(myURI).toFile().toString()
VenerableAgents
la source
Cela renvoie l'emplacement du fichier JAR. Pas ce qui était demandé.
Marquis de Lorne
0

Ceci est ma balle d'argent quand le moment de confusion se propage. (Appelez-le comme première chose principale). Par exemple, JVM est glissé pour être une version différente par IDE. Cette fonction statique recherche le processus PID en cours et ouvre VisualVM sur ce pid. La confusion s'arrête là parce que vous voulez tout et vous l'obtenez ...

  public static void callJVisualVM() {
    System.out.println("USER:DIR!:" + System.getProperty("user.dir"));
    //next search current jdk/jre
    String jre_root = null;
    String start = "vir";
    try {
        java.lang.management.RuntimeMXBean runtime =
                java.lang.management.ManagementFactory.getRuntimeMXBean();
        String jvmName = runtime.getName();
        System.out.println("JVM Name = " + jvmName);
        long pid = Long.valueOf(jvmName.split("@")[0]);
        System.out.println("JVM PID  = " + pid);
        Runtime thisRun = Runtime.getRuntime();
        jre_root = System.getProperty("java.home");
        System.out.println("jre_root:" + jre_root);
        start = jre_root.concat("\\..\\bin\\jvisualvm.exe " + "--openpid " + pid);
        thisRun.exec(start);
    } catch (Exception e) {
        System.getProperties().list(System.out);
        e.printStackTrace();
    }
}
Kurskinen
la source
-6

System.getProperty("java.class.path")

Marko Stojkovic
la source
-7

c'est le nom du répertoire actuel

String path="/home/prasad/Desktop/folderName";
File folder = new File(path);
String folderName=folder.getAbsoluteFile().getName();

c'est le chemin du répertoire courant

String path=folder.getPath();
Prasad De Silva
la source
1
L'OP voulait le répertoire de travail actuel d'où l'application était exécutée.
Leif Gruenwoldt
Il s'agit de votre répertoire personnel, et non du répertoire de travail actuel de personne, sauf peut-être le vôtre. Pas ce qui était demandé.
Marquis de Lorne