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

112

Disons que j'ai ma classe principale C:\Users\Justian\Documents\. Comment puis-je faire en sorte que mon programme montre qu'il est inclus C:\Users\Justian\Documents?

Le codage en dur n'est pas une option - il doit être adaptable s'il est déplacé vers un autre emplacement.

Je veux vider un tas de fichiers CSV dans un dossier, faire reconnaître tous les fichiers par le programme, puis charger les données et les manipuler. Je veux vraiment savoir comment accéder à ce dossier.

Justian Meyer
la source
1
jetez un œil à cet article .
Matthew J Morrison
1
Et si votre classe principale est dans un fichier jar? Quel genre de résultat voudriez-vous alors?
Mattias Nilsson
1
Pourquoi auriez-vous besoin de faire ça de toute façon?
Ed S.
1
sonne comme ce dont vous avez besoin est le répertoire dans lequel se trouvent les fichiers CSV, et que le fichier .jar puisse référencer ce répertoire, voir ma réponse si tel est le cas.
duplication possible de Obtenir le répertoire de travail actuel en Java
Kevin

Réponses:

149

Une façon serait d'utiliser la propriété système System.getProperty("user.dir"); qui vous donnera "Le répertoire de travail actuel lorsque les propriétés ont été initialisées". C'est probablement ce que vous voulez. pour savoir où la javacommande a été émise, dans votre cas dans le répertoire avec les fichiers à traiter, même si le fichier .jar réel peut résider ailleurs sur la machine. Avoir le répertoire du fichier .jar réel n'est pas très utile dans la plupart des cas.

Ce qui suit imprimera le répertoire actuel à partir duquel la commande a été appelée, quel que soit l'emplacement du fichier .class ou .jar dans lequel se trouve le fichier .class.

public class Test
{
    public static void main(final String[] args)
    {
        final String dir = System.getProperty("user.dir");
        System.out.println("current dir = " + dir);
    }
}  

si vous êtes dans /User/me/et que votre fichier .jar contenant le code ci-dessus est dans /opt/some/nested/dir/ la commande java -jar /opt/some/nested/dir/test.jar Testsera sortie current dir = /User/me.

Vous devriez également regarder en prime l'utilisation d'un bon analyseur d'arguments de ligne de commande orienté objet. Je recommande vivement JSAP , le Java Simple Argument Parser. Cela vous permettrait d'utiliser System.getProperty("user.dir")et de transmettre quelque chose d'autre pour annuler le comportement. Une solution beaucoup plus maintenable. Cela rendrait le passage dans le répertoire à traiter très facile à faire, et serait capable de se rabattre user.dirsi rien n'était passé.


la source
Je vais tester ça quand je peux. Je suis vraiment préoccupé par ce problème .jar: P
Justian Meyer
avez-vous visité le lien dans ma réponse à ce problème .jar, où je montre comment créer le fichier .jar avec ANT?
Le code de Jarrod qui renvoie le chemin absolu du répertoire de travail actuel à partir de la propriété système user.direst beaucoup plus facile à utiliser. System.getProperty ("user.dir");
74

Utilisez CodeSource#getLocation(). Cela fonctionne également très bien dans les fichiers JAR. Vous pouvez obtenir CodeSourcepar ProtectionDomain#getCodeSource()et le ProtectionDomainà son tour 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());
    }
}

Mise à jour selon le commentaire de l'OP:

Je veux vider un tas de fichiers CSV dans un dossier, faire reconnaître tous les fichiers par le programme, puis charger les données et les manipuler. Je veux vraiment savoir comment accéder à ce dossier.

Cela nécessiterait un codage en dur / la connaissance de leur chemin relatif dans votre programme. Pensez plutôt à ajouter son chemin au chemin de classe afin que vous puissiez utiliserClassLoader#getResource()

File classpathRoot = new File(classLoader.getResource("").getPath());
File[] csvFiles = classpathRoot.listFiles(new FilenameFilter() {
    @Override public boolean accept(File dir, String name) {
        return name.endsWith(".csv");
    }
});

Ou pour passer son chemin comme main()argument.

BalusC
la source
3
+1. Il y a plusieurs conditions pour que cela fonctionne; le plus important est que votre "classe principale" soit chargée à partir du système de fichiers. En Java, il n'est pas terriblement inhabituel que cette hypothèse soit fausse. Mais, si vous êtes sûr que vous chargez votre classe à partir d'un JAR sur le système de fichiers, c'est la méthode qui fonctionne.
erickson
Tout dépend, vraiment. J'essaie d'obtenir mon JAR à la compilation, mais c'est une question distincte pour le moment. Si vous pensez pouvoir aider avec cela, consultez: stackoverflow.com/questions/3152240/… . Je suis sûr que publier ceci est une infraction quelconque, mais c'est lié à ce problème. Si je peux résoudre ce problème, ce sera certainement ma réponse.
Justian Meyer
Pourquoi aurais-je besoin de coder cela en dur? J'ai déjà fait des choses similaires. Supposons que mon jar et mon dossier auront toujours une relation similaire (c'est-à-dire dans le même répertoire). Si cela était vrai, je pourrais obtenir le répertoire du fichier jar, puis le modifier pour trouver le dossier.
Justian Meyer
S'il se trouve dans le même dossier que le fichier JAR, il se trouve juste déjà dans le chemin de classe. Le mot "hardcoding" est un peu exagéré, je voulais en fait dire "connaître leur chemin par rapport au fichier JAR".
BalusC
1
@Moebius: Hein? Êtes-vous nouveau sur Java? Vérifiez le javadoc . Utilisez simplement celui-ci comme renvoyé par la getLocation()méthode. D'autres ne fonctionneront évidemment pas.
BalusC
31
File currentDirectory = new File(new File(".").getAbsolutePath());
System.out.println(currentDirectory.getCanonicalPath());
System.out.println(currentDirectory.getAbsolutePath());

Imprime quelque chose comme:

/path/to/current/directory
/path/to/current/directory/.

Notez que File.getCanonicalPath()jette une IOException cochée mais cela supprimera des choses comme ../../../

cyber-moine
la source
13
this.getClass().getClassLoader().getResource("").getPath()
Peter De Winter
la source
notez que cela renverra le chemin vers le "bin / classes /", et pas seulement "bin".
développeur android
lors du débogage d'une application en cours d'exécution à l'aide d'Intellij Idea, cela a renvoyé "/C:/Program%20Files/Java/jdk1.8.0_112/:"
vitesse du
5

Je viens d'utiliser:

import java.nio.file.Path;
import java.nio.file.Paths;

...

Path workingDirectory=Paths.get(".").toAbsolutePath();
user3696181
la source
9
Le vôtre ne fonctionne pas, celui-ci est correctPaths.get("").toAbsolutePath();
To Kra
@ToKra Si Paths.get("my/file").toAbsolutePath()j'obtiens /my/file, ce n'est certainement pas le cwd.
abergmeier
1
@abergmeier j'ai écrit "" dans la chaîne et non "mon / fichier"
To Kra
5

Si vous souhaitez obtenir votre répertoire de travail actuel, utilisez la ligne suivante

System.out.println(new File("").getAbsolutePath());
rjrajsaha
la source
4

Si vous voulez le chemin absolu du code source actuel, ma suggestion est:

String internalPath = this.getClass().getName().replace(".", File.separator);
String externalPath = System.getProperty("user.dir")+File.separator+"src";
String workDir = externalPath+File.separator+internalPath.substring(0, internalPath.lastIndexOf(File.separator));
jmamatos
la source
Cela ne fonctionne pas lorsque vous l'exécutez sur un IDE ou que vous utilisez quelque chose pour faire tourner l'instance.
Sarp Kaya
Le chemin interne est java \ lang \ Class Le chemin externe est E: \ BranchProduction1.4.0 \ FilesTestProject \ src Le répertoire de travail est E: \ BranchProduction1.4.0 \ FilesTestProject \ src \ java \ lang pourriez-vous expliquer la sortie?
JAVA
3

Qui a dit que votre classe principale était dans un fichier sur un disque dur local? Les classes sont plus souvent regroupées dans des fichiers JAR, et parfois chargées sur le réseau ou même générées à la volée.

Alors qu'est-ce que tu veux vraiment faire? Il existe probablement un moyen de le faire qui ne fait pas d'hypothèses sur l'origine des classes.

Michael Borgwardt
la source
Je veux vider un tas de fichiers CSV dans un dossier, faire reconnaître tous les fichiers par le programme, puis charger les données et les manipuler. Je veux vraiment savoir comment accéder à ce dossier.
Justian Meyer
Peut-être que je manque quelque chose, mais il semble qu'un chemin absolu fonctionnerait. Vous avez dit que vous ne pouvez pas le coder en dur, mais comment allez-vous savoir dans quel dossier chercher pour commencer?
Chris Thompson
Eh bien, le problème est que je veux l'amener sur d'autres ordinateurs, pas seulement sur le mien. Je ne vois pas comment le codage en dur du chemin fonctionnerait. "Supposons que mon fichier jar et mon dossier auront toujours une relation similaire (c'est-à-dire dans le même répertoire). Si c'était vrai, je pourrais obtenir le répertoire du fichier jar, puis le modifier pour trouver le dossier." La seule façon dont je pourrais coder en dur serait de ne pas avoir à inclure le chemin complet du disque dur vers le fichier. Peut-être que je ne peux reculer que 3 dossiers (c'est-à-dire "Documents \ Project \ Dump \ [fichier / dossier]")
Justian Meyer
Je dirais que ce que vous voulez faire, c'est obtenir un descripteur du répertoire dans lequel réside le fichier JAR. Cela répondrait-il à vos besoins?
Chris Thompson