Wie bekomme ich das aktuelle Arbeitsverzeichnis in Java?

112

Nehmen wir an, ich habe meine Hauptklasse in C:\Users\Justian\Documents\. Wie kann ich mein Programm dazu bringen, zu zeigen, dass es in ist C:\Users\Justian\Documents?

Hardcodierung ist keine Option - sie muss anpassbar sein, wenn sie an einen anderen Ort verschoben wird.

Ich möchte eine Reihe von CSV-Dateien in einem Ordner ablegen, das Programm alle Dateien erkennen lassen, dann die Daten laden und bearbeiten. Ich möchte wirklich nur wissen, wie man zu diesem Ordner navigiert.

Justian Meyer
quelle
1
Schauen Sie sich diesen Artikel an .
Matthew J Morrison
1
Was ist, wenn sich Ihre Hauptklasse in einer JAR-Datei befindet? Was für ein Ergebnis würden Sie dann wollen?
Mattias Nilsson
1
Warum sollten Sie das überhaupt jemals tun müssen?
Ed S.
1
Klingt so, als ob Sie das Verzeichnis benötigen, in dem sich die CSV-Dateien befinden, und die JAR-Datei auf dieses Verzeichnis verweisen kann. Siehe meine Antwort, wenn dies der Fall ist.

Antworten:

149

Eine Möglichkeit wäre die Verwendung der Systemeigenschaft. Dadurch erhalten System.getProperty("user.dir");Sie "Das aktuelle Arbeitsverzeichnis, als die Eigenschaften initialisiert wurden". Dies ist wahrscheinlich was Sie wollen. um herauszufinden, wo der javaBefehl ausgegeben wurde, in Ihrem Fall in dem Verzeichnis mit den zu verarbeitenden Dateien, obwohl sich die eigentliche JAR-Datei möglicherweise an einer anderen Stelle auf dem Computer befindet. Das Verzeichnis der eigentlichen JAR-Datei zu haben, ist in den meisten Fällen nicht so nützlich.

Im Folgenden wird das aktuelle Verzeichnis ausgedruckt, aus dem der Befehl aufgerufen wurde, unabhängig davon, in welcher .class- oder .jar-Datei sich die .class-Datei befindet.

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

Wenn Sie sich in befinden /User/me/und Ihre JAR-Datei mit dem obigen Code im /opt/some/nested/dir/ Befehl enthalten ist, java -jar /opt/some/nested/dir/test.jar Testwird ausgegeben current dir = /User/me.

Als Bonus sollten Sie auch einen guten objektorientierten Befehlszeilenargument-Parser verwenden. Ich empfehle JSAP , den Java Simple Argument Parser. Auf diese Weise können Sie System.getProperty("user.dir")etwas anderes verwenden und alternativ übergeben, um das Verhalten zu überschreiben. Eine viel wartbarere Lösung. Dies würde die Übergabe des zu verarbeitenden Verzeichnisses sehr einfach machen und auf etwas zurückgreifen können, user.dirwenn nichts übergeben wurde.


quelle
Ich werde das testen, wenn ich kann. Ich bin wirklich mit diesem .jar-Problem beschäftigt: P
Justian Meyer
Haben Sie den Link in meiner Antwort auf dieses .jar-Problem besucht, in dem ich zeige, wie die .jar-Datei mit ANT erstellt wird?
Der Code von Jarrod, der den aktuellen absoluten Pfad des Arbeitsverzeichnisses von System Property zurückgibt, user.dirist sehr einfach zu verwenden. System.getProperty ("user.dir");
74

Verwenden Sie CodeSource#getLocation(). Dies funktioniert auch in JAR-Dateien einwandfrei. Sie können erhalten CodeSourcevon ProtectionDomain#getCodeSource()und die ProtectionDomainwiederum können erhalten werden von 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());
    }
}

Update gemäß Kommentar des OP:

Ich möchte eine Reihe von CSV-Dateien in einem Ordner ablegen, das Programm alle Dateien erkennen lassen, dann die Daten laden und bearbeiten. Ich möchte wirklich nur wissen, wie man zu diesem Ordner navigiert.

Dies würde eine Hardcodierung / Kenntnis des relativen Pfades in Ihrem Programm erfordern. Erwägen Sie lieber, den Pfad zum Klassenpfad hinzuzufügen, damit Sie ihn verwenden könnenClassLoader#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");
    }
});

Oder um seinen Weg als main()Argument zu übergeben.

BalusC
quelle
3
+1. Es gibt verschiedene Bedingungen, damit dies funktioniert. Das wichtigste ist, dass Ihre "Hauptklasse" aus dem Dateisystem geladen wird. In Java ist es nicht ungewöhnlich, dass diese Annahme falsch ist. Aber, wenn Sie sicher sind , dass Sie Ihre Klasse auf dem Dateisystem aus einer JAR geladen werden , das ist die Methode , die funktioniert.
Erickson
Es hängt wirklich alles davon ab. Ich versuche , meine JAR zum Kompilieren zu bringen, aber das ist im Moment ein separates Problem. Wenn Sie glauben, dass Sie dabei helfen können, lesen Sie : stackoverflow.com/questions/3152240/… . Ich bin mir sicher, dass das Posten ein Verstoß ist, aber es hängt mit diesem Problem zusammen. Wenn ich das beheben kann, wird dies mit Sicherheit meine Antwort sein.
Justian Meyer
Warum sollte ich das fest codieren müssen? Ich habe ähnliche Dinge schon einmal gemacht. Angenommen, mein JAR und mein Ordner haben immer eine ähnliche Beziehung (dh im selben Verzeichnis). Wenn dies wahr wäre, könnte ich das Verzeichnis des JARs abrufen und es dann ändern, um den Ordner zu finden.
Justian Meyer
Wenn es sich im selben Ordner wie die JAR-Datei befindet, befindet es sich nur bereits im Klassenpfad. Das Wort "Hardcoding" ist etwas übertrieben, ich meinte eigentlich "ihren Pfad relativ zur JAR-Datei kennen".
BalusC
1
@Moebius: Huh? Sind Sie neu in Java? Überprüfen Sie den Javadoc . Verwenden Sie einfach genau das, was von der getLocation()Methode zurückgegeben wird. Andere werden offensichtlich nicht funktionieren.
BalusC
31
File currentDirectory = new File(new File(".").getAbsolutePath());
System.out.println(currentDirectory.getCanonicalPath());
System.out.println(currentDirectory.getAbsolutePath());

Druckt so etwas wie:

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

Beachten Sie, dass File.getCanonicalPath()eine aktivierte IOException ausgelöst wird, aber Dinge wie entfernt werden ../../../

Cyber-Mönch
quelle
13
this.getClass().getClassLoader().getResource("").getPath()
Peter De Winter
quelle
Beachten Sie, dass dadurch der Pfad zu "bin / classes /" und nicht nur zu "bin" zurückgegeben wird.
Android-Entwickler
Beim Debuggen einer laufenden Anwendung mit Intellij Idea wurde "/C:/Program%20Files/Java/jdk1.8.0_112/:" zurückgegeben
Geschwindigkeit
5

Ich habe gerade verwendet:

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

...

Path workingDirectory=Paths.get(".").toAbsolutePath();
user3696181
quelle
9
Ihr es funktioniert nicht, dies ist eines richtigPaths.get("").toAbsolutePath();
Zu Kra
@ ToKra Wenn ich das Paths.get("my/file").toAbsolutePath()bekomme /my/file, bekomme ich das definitiv nicht.
Abergmeier
1
@abergmeier Ich schrieb "" in Zeichenfolge nicht "meine / Datei"
To Kra
5

Wenn Sie Ihr aktuelles Arbeitsverzeichnis abrufen möchten, verwenden Sie die folgende Zeile

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

Wenn Sie den absoluten Pfad des aktuellen Quellcodes möchten, ist mein Vorschlag:

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
quelle
Dies funktioniert nicht, wenn Sie es auf einer IDE ausführen oder etwas zum Drehen der Instanz verwenden.
Sarp Kaya
Der interne Pfad lautet java \ lang \ Class. Der externe Pfad lautet E: \ BranchProduction1.4.0 \ FilesTestProject \ src. Das Arbeitsverzeichnis lautet E: \ BranchProduction1.4.0 \ FilesTestProject \ src \ java \ lang. Können Sie die Ausgabe erläutern?
JAVA
3

Wer sagt, dass sich Ihre Hauptklasse in einer Datei auf einer lokalen Festplatte befindet? Klassen werden häufiger in JAR-Dateien gebündelt und manchmal über das Netzwerk geladen oder sogar im laufenden Betrieb generiert.

Was möchten Sie eigentlich tun? Es gibt wahrscheinlich einen Weg, der keine Annahmen darüber macht, woher die Klassen kommen.

Michael Borgwardt
quelle
Ich möchte eine Reihe von CSV-Dateien in einem Ordner ablegen, das Programm alle Dateien erkennen lassen, dann die Daten laden und bearbeiten. Ich möchte wirklich nur wissen, wie man zu diesem Ordner navigiert.
Justian Meyer
Vielleicht fehlt mir etwas, aber es scheint, als würde ein absoluter Weg funktionieren. Sie sagten, Sie können es nicht fest codieren, aber woher wissen Sie, in welchem ​​Ordner Sie zuerst suchen müssen?
Chris Thompson
Nun, das Problem ist, dass ich es auf andere Computer übertragen möchte, nicht nur auf meine eigenen. Ich sehe nicht, wie hart der Pfad funktionieren würde. "Angenommen, mein JAR und mein Ordner haben immer eine ähnliche Beziehung (dh im selben Verzeichnis). Wenn dies zutrifft, könnte ich das Verzeichnis des JARs abrufen und es dann ändern, um den Ordner zu finden." Ich könnte es nur fest codieren, wenn ich nicht den vollständigen Pfad von der Festplatte zur Datei angeben müsste. Vielleicht kann ich nur 3 Ordner zurückgehen (dh "Dokumente \ Projekt \ Speicherauszug \ [Datei / Ordner]")
Justian Meyer
Ich würde sagen, Sie möchten ein Handle für das Verzeichnis erhalten, in dem sich die JAR-Datei befindet. Würde dies Ihre Anforderungen erfüllen?
Chris Thompson