Come ottenere la directory di lavoro corrente in Java?


112

Diciamo che ho la mia lezione principale C:\Users\Justian\Documents\. Come posso fare in modo che il mio programma dimostri che è attivo C:\Users\Justian\Documents?

L'hard-coding non è un'opzione: deve essere adattabile se viene spostato in un'altra posizione.

Voglio scaricare un mucchio di file CSV in una cartella, fare in modo che il programma riconosca tutti i file, quindi caricare i dati e manipolarli. Voglio solo sapere come navigare in quella cartella.


1
dai un'occhiata a questo articolo .
Matthew J Morrison

1
E se la tua classe principale fosse in un file jar? Che tipo di risultato vorresti allora?
Mattias Nilsson,

1
Perché mai dovresti farlo comunque?
Ed S.

1
sembra che quello di cui hai bisogno sia la directory in cui si trovano i file CSV e che il file .jar sia in grado di fare riferimento a quella directory, vedi la mia risposta se è così.

Risposte:


149

Un modo sarebbe usare la proprietà di sistema che System.getProperty("user.dir"); ti darà "La directory di lavoro corrente quando le proprietà sono state inizializzate". Questo è probabilmente quello che vuoi. per scoprire dove è javastato emesso il comando, nel tuo caso nella directory con i file da elaborare, anche se il file .jar effettivo potrebbe risiedere da qualche altra parte sulla macchina. Avere la directory del file .jar effettivo non è così utile nella maggior parte dei casi.

Quanto segue stamperà la directory corrente da cui è stato richiamato il comando indipendentemente da dove si trova il file .class o .jar.

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

se ti trovi /User/me/e il tuo file .jar contenente il codice sopra è nel /opt/some/nested/dir/ comando java -jar /opt/some/nested/dir/test.jar Testverrà visualizzato current dir = /User/me.

Dovresti anche dare un'occhiata all'uso di un buon parser di argomenti della riga di comando orientato agli oggetti. Consiglio vivamente JSAP , Java Simple Argument Parser. Questo ti consentirebbe di usare System.getProperty("user.dir")e in alternativa passare qualcos'altro per sovrastare il comportamento. Una soluzione molto più manutenibile. Ciò renderebbe il passaggio nella directory da elaborare molto facile da eseguire e sarebbe in grado di ripiegare user.dirse non fosse passato nulla.


Lo proverò quando posso. Sono davvero preoccupato per questo problema .jar: P
Justian Meyer

hai visitato il link nella mia risposta a quel problema .jar, dove mostro come costruire il file .jar con ANT?

Il codice di Jarrod che restituisce il percorso assoluto della directory di lavoro corrente dalla proprietà di sistema user.dirè molto facile da usare. System.getProperty ( "user.dir");

74

Usa CodeSource#getLocation(). Funziona bene anche con i file JAR. Puoi ottenere CodeSourceda ProtectionDomain#getCodeSource()e il ProtectionDomaina sua volta può essere ottenuto da 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());
    }
}

Aggiornamento come da commento dell'OP:

Voglio scaricare un mucchio di file CSV in una cartella, fare in modo che il programma riconosca tutti i file, quindi caricare i dati e manipolarli. Voglio solo sapere come navigare in quella cartella.

Ciò richiederebbe l'hardcoding / la conoscenza del loro percorso relativo nel tuo programma. Considera piuttosto l'aggiunta del suo percorso al classpath in modo da poter utilizzareClassLoader#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");
    }
});

O per passare il suo percorso come main()argomento.


3
+1. Ci sono diverse condizioni per far funzionare questo; la cosa più importante è che la tua "classe principale" sia caricata dal file system. In Java, non è così insolito che questa ipotesi sia falsa. Ma se sei sicuro di caricare la tua classe da un JAR sul file system, questo è il metodo che funziona.
erickson,

Dipende tutto, davvero. Sto cercando di compilare il mio JAR, ma al momento questo è un problema separato. Se pensi di poter aiutare con questo, controlla: stackoverflow.com/questions/3152240/… . Sono sicuro che pubblicare questo messaggio sia un'infrazione di qualche tipo, ma è correlato a questo problema. Se riesco a risolverlo, questa sarà sicuramente la mia risposta.
Justian Meyer

Perché dovrei aver bisogno di codificarlo? Ho già fatto cose simili in passato. Supponiamo che il mio jar e la mia cartella abbiano sempre una relazione simile (cioè nella stessa directory). Se questo fosse vero, potrei ottenere la directory del jar, quindi modificarla per trovare la cartella.
Justian Meyer

Se si trova nella stessa cartella del file JAR, è già presente nel classpath. La parola "hardcoding" è un po 'esagerata, in realtà intendevo "conoscere il loro percorso relativo al file JAR".
BalusC

1
@ Moebius: eh? Sei nuovo in Java? Controlla il file javadoc . Usa esattamente quello restituito dal getLocation()metodo. Altri ovviamente non funzioneranno.
BalusC

31
File currentDirectory = new File(new File(".").getAbsolutePath());
System.out.println(currentDirectory.getCanonicalPath());
System.out.println(currentDirectory.getAbsolutePath());

Stampa qualcosa come:

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

Nota che File.getCanonicalPath()genera un'IOException selezionata ma rimuoverà cose come ../../../


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

nota che questo restituirà il percorso di "bin / classes /" e non solo di "bin".
sviluppatore Android

durante il debug di un'applicazione in esecuzione utilizzando Intellij Idea, questo ha restituito "/C:/Program%20Files/Java/jdk1.8.0_112/:"
velocità

5

Ho appena usato:

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

...

Path workingDirectory=Paths.get(".").toAbsolutePath();

9
Il tuo non funziona, questo è correttoPaths.get("").toAbsolutePath();
Per Kra

@ ToKra Se lo faccio Paths.get("my/file").toAbsolutePath()ottengo /my/file, che sicuramente non è il cwd.
abergmeier

1
@abergmeier ho scritto "" nella stringa non "mio / file"
A Kra

5

Se si desidera ottenere la directory di lavoro corrente, utilizzare la riga seguente

System.out.println(new File("").getAbsolutePath());

4

Se vuoi il percorso assoluto del codice sorgente corrente, il mio suggerimento è:

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

Questo non funziona quando lo esegui su un IDE o usi qualcosa per far girare l'istanza.
Sarp Kaya

Il percorso interno è java \ lang \ Class Il percorso esterno è E: \ BranchProduction1.4.0 \ FilesTestProject \ src La directory di lavoro è E: \ BranchProduction1.4.0 \ FilesTestProject \ src \ java \ lang potresti spiegare l'output?
JAVA

3

Chi dice che la tua classe principale è in un file su un disco rigido locale? Le classi sono più spesso raggruppate all'interno di file JAR e talvolta caricate sulla rete o addirittura generate al volo.

Quindi cosa vuoi fare effettivamente? Probabilmente c'è un modo per farlo che non fa supposizioni sulla provenienza delle classi.


Voglio scaricare un mucchio di file CSV in una cartella, fare in modo che il programma riconosca tutti i file, quindi caricare i dati e manipolarli. Voglio solo sapere come navigare in quella cartella.
Justian Meyer,

Forse mi manca qualcosa ma sembra che un percorso assoluto funzionerebbe. Hai detto che non puoi codificarlo come hardcoded, ma come farai a sapere in quale cartella cercare?
Chris Thompson,

Il problema è che voglio portarlo su altri computer, non solo sul mio. Non vedo come funzionerebbe l'hardcoding del percorso. "Supponiamo che il mio jar e la mia cartella avranno sempre una relazione simile (cioè nella stessa directory). Se fosse vero, potrei ottenere la directory del jar, quindi modificarla per trovare la cartella." L'unico modo per codificare sarebbe se non dovessi includere il percorso completo dal disco rigido al file. Forse posso tornare indietro di sole 3 cartelle (ad esempio "Documents \ Project \ Dump \ [file / folder]")
Justian Meyer,

Direi che quello che vuoi fare è ottenere un handle per la directory in cui risiede il file jar. Questo soddisferebbe le tue esigenze?
Chris Thompson
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.