Как я могу изменить текущий рабочий каталог из программы Java? Все, что я смог найти в этой проблеме, утверждает, что вы просто не можете этого сделать, но я не могу поверить, что это действительно так.
У меня есть фрагмент кода, который открывает файл с использованием жестко заданного относительного пути к файлу из каталога, в котором он обычно запускается, и я просто хочу иметь возможность использовать этот код из другой Java-программы, не запуская его изнутри конкретный каталог. Кажется, что вы должны просто быть в состоянии звонить System.setProperty( "user.dir", "/path/to/dir" )
, но, насколько я могу понять, звонить по этой линии просто молча не получается и ничего не делает.
Я бы понял, если бы Java не позволяла вам сделать это, если бы не факт, что он позволяет вам получить текущий рабочий каталог и даже позволяет открывать файлы, используя относительные пути к файлам ....
Ответы:
Не существует надежного способа сделать это на чистой Java. Установка
user.dir
свойства черезSystem.setProperty()
илиjava -Duser.dir=...
, кажется, влияет на последующее созданиеFiles
, но не напримерFileOutputStreams
.File(String parent, String child)
Конструктор может помочь , если вы строите свой путь к каталогу отдельно от пути к файлу, что позволяет легче обменивать.Альтернатива - настроить скрипт для запуска Java из другого каталога или использовать собственный код JNI, как предложено ниже .
Соответствующая ошибка Sun была закрыта в 2008 году как «не будет исправлена».
источник
new FileOutputStream("foo.txt").close();
создает файл в исходном рабочем каталоге, даже если программа изменила user.dir.Если вы запустите свою унаследованную программу с ProcessBuilder , вы сможете указать ее рабочий каталог .
источник
Там является способ сделать это , используя системное свойство «user.dir». Ключевая часть, которую нужно понять, - это то, что getAbsoluteFile () должен быть вызван (как показано ниже), иначе относительные пути будут разрешены в соответствии со значением по умолчанию «user.dir».
источник
user.dir
. Тот факт, что абсолютный путь становится критическим, доказывает это.Можно изменить PWD, используя JNA / JNI для вызова libc. Ребята из JRuby имеют удобную библиотеку Java для выполнения вызовов POSIX, которая называется jna-posix. Вот информация о maven.
Вы можете увидеть пример его использования здесь (код Clojure, извините). Посмотрите на функцию chdirToRoot
источник
user.dir
системное свойство,File.getAbsolutePath()
произойдет сопоставлениеuser.dir
, в то время как путь в Файле сопоставляется с рабочим каталогом ОС.Как уже упоминалось, вы не можете изменить CWD JVM, но если вы должны были запустить другой процесс с помощью Runtime.exec (), вы можете использовать перегруженный метод, который позволяет вам указать рабочий каталог. Это на самом деле не для запуска вашей Java-программы в другом каталоге, но во многих случаях, когда нужно запустить другую программу, например, скрипт Perl, вы можете указать рабочий каталог этого скрипта, оставив рабочий каталог JVM без изменений.
Смотрите Runtime.exec javadocs
В частности,
где
dir
находится рабочий каталог для запуска подпроцессаисточник
Если я правильно понимаю, Java-программа начинается с копии текущих переменных среды. Любые изменения через
System.setProperty(String, String)
изменяют копию, а не исходные переменные среды. Не то чтобы это дало основательную причину тому, почему Sun выбрала такое поведение, но, возможно, оно проливает немного света ...источник
-D
. Но я согласен, при запуске JVM предопределенные свойства, такие какuser.dir
копирование из ОС и их последующее изменение, не помогают.user.dir
влияетFile.getAbsolutePath()
иFile.getCanonicalPath()
, но не на представление ОС о рабочем каталоге, которое определяет способ разрешения имен файлов при доступе к файлам.Рабочий каталог - это функция операционной системы (устанавливается при запуске процесса). Почему бы вам просто не передать собственное свойство System (
-Dsomeprop=/my/path
) и использовать его в своем коде в качестве родителя вашего файла:источник
Умнее / проще сделать здесь - просто изменить свой код так, чтобы вместо открытия файла предполагалось, что он существует в текущем рабочем каталоге (я предполагаю, что вы делаете что-то вроде
new File("blah.txt")
, просто создайте путь к файлу самостоятельно.Пусть пользователь перейдет в базовый каталог, прочитает его из файла конфигурации, обратится к тому,
user.dir
если другие свойства не могут быть найдены, и т. Д. Но гораздо проще улучшить логику в вашей программе, чем изменить способ переменные окружения работают.источник
Я пытался вызвать
String oldDir = System.setProperty("user.dir", currdir.getAbsolutePath());
Вроде работает. Но
File myFile = new File("localpath.ext"); InputStream openit = new FileInputStream(myFile);
бросает
FileNotFoundException
хотяmyFile.getAbsolutePath()
показывает правильный путь. Я прочитал это . Я думаю, что проблема заключается в:
Решение может быть:
File myFile = new File(System.getPropety("user.dir"), "localpath.ext");
Он создает файл Object как абсолютный с текущим каталогом, который известен JVM. Но этот код должен существовать в используемом классе, он требует замены повторно используемых кодов.
~~~~ JcHartmut
источник
Ты можешь использовать
после
Будет печатать
источник
System.setProperty("user.dir", "/some/directory")
Другой возможный ответ на этот вопрос может зависеть от причины, по которой вы открываете файл. Это файл свойств или файл, имеющий некоторую конфигурацию, связанную с вашим приложением?
В этом случае вы можете попытаться загрузить файл через загрузчик classpath, таким образом вы можете загрузить любой файл, к которому у Java есть доступ.
источник
Если вы запускаете свои команды в оболочке, вы можете написать что-то вроде «java -cp» и добавить любые каталоги, которые вы хотите, разделив «:», если java не находит что-то в одном каталоге, он попытается найти их в других каталогах, что это то, что я делаю
источник
Вы можете изменить фактический рабочий каталог процесса, используя JNI или JNA.
С JNI вы можете использовать встроенные функции для установки каталога. Метод POSIX есть
chdir()
. На Windows вы можете использоватьSetCurrentDirectory()
.С JNA вы можете обернуть нативные функции в связыватели Java.
Для Windows:
Для систем POSIX:
источник
Использовать FileSystemView
источник