Wie kann ich das aktuelle Arbeitsverzeichnis in einem Java-Programm ändern? Alles, was ich über das Problem herausfinden konnte, besagt, dass man es einfach nicht kann, aber ich kann nicht glauben, dass das wirklich der Fall ist.
Ich habe einen Code, der eine Datei unter Verwendung eines fest codierten relativen Dateipfads aus dem Verzeichnis öffnet, in dem sie normalerweise gestartet wurde, und ich möchte diesen Code nur in einem anderen Java-Programm verwenden können, ohne ihn von innen starten zu müssen ein bestimmtes Verzeichnis. Es scheint, als ob Sie nur anrufen können sollten System.setProperty( "user.dir", "/path/to/dir" )
, aber soweit ich herausfinden kann, schlägt das Anrufen dieser Leitung nur stillschweigend fehl und führt zu nichts.
Ich würde verstehen , wenn Java nicht erlauben Ihnen , dies zu tun, wenn es nicht für die Tatsache, dass es Ihnen erlaubt , zu erhalten das aktuelle Arbeitsverzeichnis, und ermöglicht es Ihnen auch zum Öffnen von Dateien relativen Dateipfaden verwenden ....
quelle
Antworten:
In reinem Java gibt es keine zuverlässige Möglichkeit, dies zu tun. Das Festlegen der
user.dir
Eigenschaft überSystem.setProperty()
oderjava -Duser.dir=...
scheint nachfolgende Kreationen von zu beeinflussenFiles
, jedoch nicht zFileOutputStreams
.Der
File(String parent, String child)
Konstruktor kann helfen, wenn Sie Ihren Verzeichnispfad getrennt von Ihrem Dateipfad erstellen, um das Austauschen zu vereinfachen.Eine Alternative besteht darin, ein Skript zum Ausführen von Java aus einem anderen Verzeichnis einzurichten oder nativen JNI-Code wie unten vorgeschlagen zu verwenden .
Der relevante Sun-Fehler wurde 2008 geschlossen, da "nicht behoben werden kann".
quelle
new FileOutputStream("foo.txt").close();
Erstellt die Datei im ursprünglichen Arbeitsverzeichnis, auch wenn user.dir vom Programm geändert wird.Wenn Sie Ihr Legacy - Programm mit laufen Process , werden Sie in der Lage sein , seine Arbeit geben Verzeichnis .
quelle
Es gibt eine Möglichkeit, dies mit der Systemeigenschaft "user.dir" zu tun. Der Schlüssel zum Verständnis ist, dass getAbsoluteFile () aufgerufen werden muss (wie unten gezeigt), sonst werden relative Pfade gegen den Standardwert "user.dir" aufgelöst.
quelle
user.dir
. Die Tatsache, dass der absolute Pfad kritisch wird, beweist es.Es ist möglich, die PWD mithilfe von JNA / JNI zu ändern, um libc aufzurufen. Die JRuby-Leute haben eine praktische Java-Bibliothek für POSIX-Aufrufe namens jna-posix. Hier sind die Maven-Informationen
Ein Beispiel für die Verwendung finden Sie hier (Clojure-Code, sorry). Schauen Sie sich die Funktion chdirToRoot an
quelle
user.dir
Systemeigenschaft ändern ,File.getAbsolutePath()
wird gegen aufgelöstuser.dir
, während der Pfadname in Datei gegen das Arbeitsverzeichnis des Betriebssystems aufgelöst wird.Wie bereits erwähnt, können Sie die CWD der JVM nicht ändern. Wenn Sie jedoch einen anderen Prozess mit Runtime.exec () starten, können Sie die überladene Methode verwenden, mit der Sie das Arbeitsverzeichnis angeben können. Dies ist nicht wirklich zum Ausführen Ihres Java-Programms in einem anderen Verzeichnis gedacht. In vielen Fällen, in denen ein anderes Programm wie beispielsweise ein Perl-Skript gestartet werden muss, können Sie das Arbeitsverzeichnis dieses Skripts angeben, während das Arbeitsverzeichnis der JVM unverändert bleibt.
Siehe Runtime.exec javadocs
Speziell,
Wo
dir
befindet sich das Arbeitsverzeichnis, in dem der Unterprozess ausgeführt werden soll?quelle
Wenn ich das richtig verstehe, beginnt ein Java-Programm mit einer Kopie der aktuellen Umgebungsvariablen. Alle Änderungen über ändern
System.setProperty(String, String)
die Kopie, nicht die ursprünglichen Umgebungsvariablen. Nicht, dass dies einen gründlichen Grund dafür liefert, warum Sun dieses Verhalten gewählt hat, aber vielleicht wirft es ein wenig Licht ...quelle
-D
. Aber ich bin damit einverstanden, dass beim Start von JVM vordefinierte Eigenschaften wieuser.dir
das Kopieren vom Betriebssystem und das spätere Ändern nicht helfen.user.dir
wirkt sich aufFile.getAbsolutePath()
undFile.getCanonicalPath()
nicht auf die Vorstellung des Betriebssystems vom Arbeitsverzeichnis aus, die vorschreibt, wie Dateipfadnamen beim Zugriff auf Dateien aufgelöst werden.Das Arbeitsverzeichnis ist eine Betriebssystemfunktion (festgelegt, wenn der Prozess gestartet wird). Warum übergeben Sie nicht einfach Ihre eigene Systemeigenschaft (
-Dsomeprop=/my/path
) und verwenden diese in Ihrem Code als übergeordnetes Element Ihrer Datei:quelle
Das klügere / einfachere, was Sie hier tun können, ist, einfach Ihren Code so zu ändern, dass anstatt die Datei zu öffnen, vorausgesetzt, dass sie im aktuellen Arbeitsverzeichnis vorhanden ist (ich gehe davon aus, dass Sie so etwas tun
new File("blah.txt")
, erstellen Sie einfach den Pfad zur Datei selbst.Lassen Sie den Benutzer das Basisverzeichnis übergeben, lesen Sie es aus einer Konfigurationsdatei, greifen Sie darauf zurück,
user.dir
wenn die anderen Eigenschaften nicht gefunden werden können usw. Es ist jedoch viel einfacher, die Logik in Ihrem Programm zu verbessern, als zu ändern, wie Umgebungsvariablen funktionieren.quelle
Ich habe versucht aufzurufen
String oldDir = System.setProperty("user.dir", currdir.getAbsolutePath());
Es scheint zu funktionieren. Aber
File myFile = new File("localpath.ext"); InputStream openit = new FileInputStream(myFile);
wirft einen
FileNotFoundException
obwohlmyFile.getAbsolutePath()
zeigt den richtigen Pfad. Ich habe diese Zeilen lesen . Ich denke das Problem ist:
Die Lösung kann sein:
File myFile = new File(System.getPropety("user.dir"), "localpath.ext");
Es wird ein Dateiobjekt als absolutes mit dem aktuellen Verzeichnis erstellt, das der JVM bekannt ist. Dieser Code sollte jedoch in einer verwendeten Klasse vorhanden sein und muss wiederverwendete Codes ändern.
~~~~ JcHartmut
quelle
Sie können verwenden
nach dem
Wird gedruckt
quelle
System.setProperty("user.dir", "/some/directory")
Die andere mögliche Antwort auf diese Frage hängt möglicherweise vom Grund ab, aus dem Sie die Datei öffnen. Handelt es sich um eine Eigenschaftendatei oder um eine Datei, deren Konfiguration sich auf Ihre Anwendung bezieht?
Wenn dies der Fall ist, können Sie versuchen, die Datei über den Klassenpfadlader zu laden. Auf diese Weise können Sie jede Datei laden, auf die Java Zugriff hat.
quelle
Wenn Sie Ihre Befehle in einer Shell ausführen, können Sie etwas wie "java -cp" schreiben und alle Verzeichnisse hinzufügen, die durch ":" getrennt werden sollen. Wenn Java etwas in einem Verzeichnis nicht findet, versucht es, es in den anderen Verzeichnissen zu finden ist was ich tue.
quelle
Sie können das tatsächliche Arbeitsverzeichnis des Prozesses mithilfe von JNI oder JNA ändern.
Mit JNI können Sie native Funktionen verwenden, um das Verzeichnis festzulegen . Die POSIX-Methode ist
chdir()
. Unter Windows können Sie verwendenSetCurrentDirectory()
.Mit JNA können Sie die nativen Funktionen in Java-Ordner einbinden.
Für Windows:
Für POSIX-Systeme:
quelle
Verwenden Sie FileSystemView
quelle