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?


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.


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.


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

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

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

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

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.


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

2
Cela renvoie l'emplacement du fichier JAR. Pas ce qui était demandé.
Marquis de Lorne

22
this.getClass().getClassLoader().getResource("").getPath()

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

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.


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


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.


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;
    }

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")...


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,


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

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


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

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.