So erhalten Sie den absoluten Pfad zur Datei im Ordner / resources Ihres Projekts

88

Nehmen Sie das Standard-Maven-Setup an.

Angenommen, Sie haben in Ihrem Ressourcenordner eine Datei abc.

Wie kann ich in Java den absoluten Pfad zur Datei erhalten?

James Raitsev
quelle
Möchten Sie ein Maven-Plugin schreiben? Oder möchten Sie auf die Datei zugreifen, wenn Ihr Programm ausgeführt wird?
Gyro Gearless
Siehe auch
Vadzim
Je nach Situation gibt es drei Lösungsvarianten: stackoverflow.com/a/56327069/715269
Gangnus

Antworten:

68

Sie können die ClassLoader.getResourceMethode verwenden, um die richtige Ressource zu erhalten.

URL res = getClass().getClassLoader().getResource("abc.txt");
File file = Paths.get(res.toURI()).toFile();
String absolutePath = file.getAbsolutePath();

ODER

Obwohl dies möglicherweise nicht immer funktioniert, ist eine einfachere Lösung -

Sie können ein FileObjekt erstellen und die folgende getAbsolutePathMethode verwenden:

File file = new File("resources/abc.txt");
String absolutePath = file.getAbsolutePath();
Rahul Bobhate
quelle
8
Ein Ratschlag mit eingeschränkter Verwendung, da das Arbeitsverzeichnis als Maven-Root fungiert. Und selbst dann sollten Sie lieber target/classes/abc.txtauf die Datei verweisen, da dies der kanonische Ort ist, an dem Maven nach der Verarbeitung Ressourcendateien ablegt (z. B. hat das Maven-Resources-Plugin möglicherweise die Eigenschaftssubstitution in abc.txt durchgeführt). Es ist viel besser, abc.txt über getResource () aus dem Klassenpfad zu verwenden.
Gyro Gearless
2
Was ist, wenn ein Endbenutzer Ihre Anwendung als ausführbare JAR ausführt? Dann wird es überhaupt keine physische Datei geben. Dies ist ein weiterer Grund, warum Sie getResource () verwenden und z. B. einen Eingabestream öffnen sollten, je nachdem, was Sie damit tun möchten.
Matthew Wise
6
Kann dies als richtige Antwort entfernt werden? @ Karol S antwortete unten - das sollte die richtige Antwort sein (daher die Diskrepanz zwischen den Stimmen)
DanGordon
3
Falsche Antwort. Bitte beziehen Sie sich auf die Antwort von @Karol
bhathiya-perera
164

Der richtige Weg, der tatsächlich funktioniert:

URL resource = YourClass.class.getResource("abc");
Paths.get(resource.toURI()).toFile();

Es spielt jetzt keine Rolle, wo sich die Datei im Klassenpfad physisch befindet. Sie wird gefunden, solange die Ressource tatsächlich eine Datei und kein JAR-Eintrag ist.

(Das scheinbar Offensichtliche new File(resource.getPath())funktioniert nicht für alle Pfade! Der Pfad ist immer noch URL-codiert!)

Karol S.
quelle
5
Oder vermutlich könnten Sie einfach Folgendes tun: new File(resource.toURI()).getAbsolutePath();(dh ich glaube nicht, dass Sie das Pfadobjekt benötigen?)
Dan King
1
Guter Tipp zum toURI (), dies vermeidet Leerzeichen in Ihrem Pfad, die als% 20 herauskommen!
Matthew Wise
28
Vielen Dank! Das hat bei mir fast geklappt. Aber ich musste eine Änderung vornehmen: YourClass.class.getClassLoader (). GetResource ("abc");
Yngwietiger
Sie könnten alternativ tun, new File(YourClass.class.getResource("abc").toURI().getPath())wenn Sie wollten.
Mike Rylander
2
Ich verstehe nicht, wie dies für so viele Menschen ohne den ersten Schrägstrich .getResource("/abc")
funktioniert hat
26

Sie müssen den Pfad angeben, von dem aus gestartet wurde /

URL resource = YourClass.class.getResource("/abc");
Paths.get(resource.toURI()).toFile();
Hett
quelle
12

Erstellen Sie die classLoader-Instanz der Klasse, die Sie benötigen, und greifen Sie dann einfach auf die Dateien oder Ressourcen zu. Jetzt greifen Sie mit der getPath()Methode dieser Klasse auf den Pfad zu .

 ClassLoader classLoader = getClass().getClassLoader();
 String path  = classLoader.getResource("chromedriver.exe").getPath();
 System.out.println(path);
Kirit Thakrar
quelle
1

So geben Sie eine Datei oder einen Dateipfad zurück

URL resource = YourClass.class.getResource("abc");
File file = Paths.get(resource.toURI()).toFile(); // return a file
String filepath = Paths.get(resource.toURI()).toFile().getAbsolutePath();  // return file path
Emmanuel Osimosu
quelle
0

Auf dem Weg zum absoluten Weg gibt es zwei Probleme:

  1. Die gefundene Platzierung befindet sich nicht dort, wo die Quelldateien liegen, sondern dort, wo die Klasse gespeichert wird. Und der Ressourcenordner wird mit ziemlicher Sicherheit irgendwo im Quellordner des Projekts liegen.
  2. Dieselben Funktionen zum Abrufen der Ressource funktionieren unterschiedlich, wenn die Klasse in einem Plugin oder in einem Paket direkt im Arbeitsbereich ausgeführt wird.

Der folgende Code gibt uns alle nützlichen Pfade:

    URL localPackage = this.getClass().getResource("");
    URL urlLoader = YourClassName.class.getProtectionDomain().getCodeSource().getLocation();
    String localDir = localPackage.getPath();
    String loaderDir = urlLoader.getPath();
    System.out.printf("loaderDir = %s\n localDir = %s\n", loaderDir, localDir);

Hier werden beide Funktionen untersucht, die zur Lokalisierung des Ressourcenordners verwendet werden können. Was classkann es in jeder Art und Weise bekommen werden, statisch oder dynamisch.


Wenn sich das Projekt nicht im Plugin befindet, wird der Code in JUnit gedruckt, wenn er ausgeführt wird:

loaderDir = /C:.../ws/source.dir/target/test-classes/
 localDir = /C:.../ws/source.dir/target/test-classes/package/

Um zu src / rest / resources zu gelangen, sollten wir den Dateibaum auf und ab gehen. Beide Methoden können verwendet werden. Beachten Sie, dass wir getResource(resourceFolderName)diesen Ordner nicht verwenden können , da er sich nicht im Zielordner befindet. Ich hoffe, niemand legt Ressourcen in die erstellten Ordner.


Wenn sich die Klasse in dem Paket befindet, das sich im Plugin befindet, lautet die Ausgabe desselben Tests:

loaderDir = /C:.../ws/plugin/bin/
 localDir = /C:.../ws/plugin/bin/package/

Also sollten wir wieder den Ordnerbaum auf und ab gehen.


Am interessantesten ist der Fall, wenn das Paket im Plugin gestartet wird . Zum Beispiel als JUnit-Plugin-Test. Die Ausgabe ist:

loaderDir = /C:.../ws/plugin/
 localDir = /package/

Hier können wir den absoluten Pfad erhalten, der nur die Ergebnisse beider Funktionen kombiniert . Und es ist nicht genug. Dazwischen sollten wir den lokalen Pfad des Ortes, an dem sich die Klassenpakete befinden, relativ zum Plugin-Ordner einfügen. Wahrscheinlich müssen Sie etwas wie srcoder src/test/resourcehier einfügen .

Sie können den Code in Ihren einfügen und die Pfade anzeigen, die Sie haben.

Gangnus
quelle