Получение текущего рабочего каталога в Java
Я хочу получить доступ к своему текущему рабочему каталогу, используя
String current = new java.io.File( "." ).getCanonicalPath();
System.out.println("Current dir:"+current);
String currentDir = System.getProperty("user.dir");
System.out.println("Current dir using System:" +currentDir);
Выход:
Current dir: C:\WINDOWS\system32
Current dir using System: C:\WINDOWS\system32
Мой вывод неверен, потому что диск C не является моим текущим каталогом. Нужна помощь в этом отношении.
28 ответов
public class JavaApplication1 {
public static void main(String[] args) {
System.out.println("Working Directory = " +
System.getProperty("user.dir"));
}
}
Это напечатает полный абсолютный путь от того места, где было инициализировано ваше приложение.
Смотрите: http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html
С помощью java.nio.file.Path
а также java.nio.file.Paths
Вы можете сделать следующее, чтобы показать, что Java считает вашим текущим путем. Это для 7 и далее, и использует NIO.
Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
System.out.println("Current relative path is: " + s);
Это выводы Current relative path is: /Users/george/NetBeansProjects/Tutorials
это в моем случае, где я провел класс. Построение путей относительным способом, без использования начального разделителя для указания того, что вы строите абсолютный путь, будет использовать этот относительный путь в качестве начальной точки.
Следующее работает на Java 7 и выше (см. Здесь для документации).
import java.nio.file.Paths;
Paths.get(".").toAbsolutePath().normalize().toString();
Я нашел это решение в комментариях, которое лучше других и более переносимо:
String cwd = new File("").getAbsolutePath();
Это даст вам путь вашего текущего рабочего каталога:
Path path = FileSystems.getDefault().getPath(".");
И это даст вам путь к файлу с именем "Foo.txt" в рабочем каталоге:
Path path = FileSystems.getDefault().getPath("Foo.txt");
Редактировать: Чтобы получить абсолютный путь к текущему каталогу из корня файловой системы:
Path path = FileSystems.getDefault().getPath(".").toAbsolutePath();
Что заставляет вас думать, что c:\windows\system32 не является вашим текущим каталогом? user.dir
свойство явно должно быть "текущим рабочим каталогом пользователя".
Другими словами, если вы не запускаете Java из командной строки, c:\windows\system32, вероятно, является вашим CWD. То есть, если вы дважды щелкнете, чтобы запустить вашу программу, CWD вряд ли будет каталогом, из которого вы дважды щелкнете.
Редактировать: Похоже, что это верно только для старых версий Windows и / или Java.
Использование CodeSource#getLocation()
,
Это прекрасно работает и в JAR-файлах. Вы можете получить CodeSource
от ProtectionDomain#getCodeSource()
и ProtectionDomain
в свою очередь может быть получен 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());
}
}
Как правило, как объект File:
File getCwd() {
return new File("").getAbsoluteFile();
}
Вы можете захотеть иметь полную квалифицированную строку, например, "D:/a/b/c", выполнив
getCwd().getAbsolutePath()
Я надеюсь, что вы хотите получить доступ к текущему каталогу, включая пакет, т.е. если ваша Java-программа находится в c:\myApp\com\foo\src\service\MyTest.java
и вы хотите печатать до c:\myApp\com\foo\src\service
тогда вы можете попробовать следующий код:
String myCurrentDir = System.getProperty("user.dir")
+ File.separator
+ System.getProperty("sun.java.command")
.substring(0, System.getProperty("sun.java.command").lastIndexOf("."))
.replace(".", File.separator);
System.out.println(myCurrentDir);
Примечание. Этот код тестируется только в Windows с Oracle JRE.
В Linux, когда вы запускаете файл JAR из терминала, оба возвращают одинаковые String
: "/ home / CurrentUser", где бы вы ни находились. Это зависит только от того, какой текущий каталог вы используете со своим терминалом, когда вы запускаете файл JAR.
Paths.get("").toAbsolutePath().toString();
System.getProperty("user.dir");
Если твой Class
с main
будет называться MainClass
затем попробуйте:
MainClass.class.getProtectionDomain().getCodeSource().getLocation().getFile();
Это вернет String
с абсолютным путем к файлу jar.
При использовании Windows user.dir возвращает каталог, как и ожидалось, но НЕ при запуске приложения с повышенными правами (запуск от имени администратора), в этом случае вы получаете C:\WINDOWS\system32
Текущий рабочий каталог определяется по-разному в разных реализациях Java. Для определенной версии до Java 7 не было последовательного способа получить рабочий каталог. Вы можете обойти это, запустив файл Java с -D
и определение переменной для хранения информации
Что-то вроде
java -D com.mycompany.workingDir="%0"
Это не совсем верно, но вы поняли идею. затем System.getProperty("com.mycompany.workingDir")
...
Укажите, что это проверено только в Windows
но я думаю, что он отлично работает на других операционных системах [ Linux,MacOs,Solaris
]:).
У меня было 2 .jar
файлы в том же каталоге. Я хотел от одного .jar
файл для запуска другого .jar
файл, который находится в том же каталоге.
Проблема в том, что когда вы запускаете его из cmd
текущий каталог system32
,
Предупреждение!
- Кажется, что приведенное ниже работает очень хорошо во всех тестах, которые я сделал, даже с именем папки
;][[;'57f2g34g87-8+9-09!2#@!$%^^&()
или же()%&$%^@#
это работает хорошо. - Я использую
ProcessBuilder
со следующим ниже:
..
//The class from which i called this was the class `Main`
String path = getBasePathForClass(Main.class);
String applicationPath= new File(path + "application.jar").getAbsolutePath();
System.out.println("Directory Path is : "+applicationPath);
//Your know try catch here
//Mention that sometimes it doesn't work for example with folder `;][[;'57f2g34g87-8+9-09!2#@!$%^^&()`
ProcessBuilder builder = new ProcessBuilder("java", "-jar", applicationPath);
builder.redirectErrorStream(true);
Process process = builder.start();
//...code
getBasePathForClass(Class<?> classs)
:
/**
* Returns the absolute path of the current directory in which the given
* class
* file is.
*
* @param classs
* @return The absolute path of the current directory in which the class
* file is.
* @author GOXR3PLUS[StackOverFlow user] + bachden [StackOverFlow user]
*/
public static final String getBasePathForClass(Class<?> classs) {
// Local variables
File file;
String basePath = "";
boolean failed = false;
// Let's give a first try
try {
file = new File(classs.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
basePath = file.getParent();
} else {
basePath = file.getPath();
}
} catch (URISyntaxException ex) {
failed = true;
Logger.getLogger(classs.getName()).log(Level.WARNING,
"Cannot firgue out base path for class with way (1): ", ex);
}
// The above failed?
if (failed) {
try {
file = new File(classs.getClassLoader().getResource("").toURI().getPath());
basePath = file.getAbsolutePath();
// the below is for testing purposes...
// starts with File.separator?
// String l = local.replaceFirst("[" + File.separator +
// "/\\\\]", "")
} catch (URISyntaxException ex) {
Logger.getLogger(classs.getName()).log(Level.WARNING,
"Cannot firgue out base path for class with way (2): ", ex);
}
}
// fix to run inside eclipse
if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
|| basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
basePath = basePath.substring(0, basePath.length() - 4);
}
// fix to run inside netbeans
if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
basePath = basePath.substring(0, basePath.length() - 14);
}
// end fix
if (!basePath.endsWith(File.separator)) {
basePath = basePath + File.separator;
}
return basePath;
}
Для Java 11 вы также можете использовать:
var path = Path.of(".").toRealPath();
Предположим, что вы пытаетесь запустить свой проект внутри затмения, или netbean, или в одиночку из командной строки. Я должен написать метод, чтобы исправить это
public static final String getBasePathForClass(Class<?> clazz) {
File file;
try {
String basePath = null;
file = new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
basePath = file.getParent();
} else {
basePath = file.getPath();
}
// fix to run inside eclipse
if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
|| basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
basePath = basePath.substring(0, basePath.length() - 4);
}
// fix to run inside netbean
if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
basePath = basePath.substring(0, basePath.length() - 14);
}
// end fix
if (!basePath.endsWith(File.separator)) {
basePath = basePath + File.separator;
}
return basePath;
} catch (URISyntaxException e) {
throw new RuntimeException("Cannot firgue out base path for class: " + clazz.getName());
}
}
Чтобы использовать везде, где вы хотите получить базовый путь для чтения файла, вы можете передать свой якорный класс вышеуказанному методу, результат может быть тем, что вам нужно:D
Лучший,
Это очень запутанная тема, и нам нужно понять некоторые концепции, прежде чем предлагать реальное решение.
Файл и NIO File Api подходят с относительными путями
""
или"."
использует внутренне значение системного параметра для определения места возврата.The
"user.dir
" значение основано на рабочем каталоге USER, и поведение этого значения зависит от операционной системы и способа выполнения jar.Например, выполнение JAR из Linux с помощью Проводника (открытие его двойным щелчком) установит
user.dir
с домашним каталогом пользователя, независимо от местоположения jar. Если тот же jar-файл выполняется из командной строки, он вернет местоположение jar-файла, потому что каждыйcd
Команда для расположения jar изменила рабочий каталог.
Сказав это, решения, использующиеJava NIO
,Files
или свойство будет работать для всех сценариев так, как имеет правильное значение.
String userDirectory = System.getProperty("user.dir");
String userDirectory2 = new File("").getAbsolutePath();
String userDirectory3 = Paths.get("").toAbsolutePath().toString();
Мы могли бы использовать следующий код:
new File(MyApp.class.getProtectionDomain()
.getCodeSource()
.getLocation()
.toURI().getPath())
.getParent();
чтобы получить текущее местоположение исполняемого JAR, и лично я использовал следующий подход, чтобы получить ожидаемое местоположение и переопределить"user.dir"
системное свойство в самом начале приложения. Итак, позже, когда будут использоваться другие подходы, я всегда буду получать ожидаемые значения.
Подробнее здесь -> https://blog.adamgamboa.dev/getting-current-directory-path-in-java/
public class MyApp {
static {
//This static block runs at the very begin of the APP, even before the main method.
try{
File file = new File(MyApp.class.getProtectionDomain().getCodeSource()
.getLocation().toURI().getPath());
String basePath = file.getParent();
//Overrides the existing value of "user.dir"
System.getProperties().put("user.dir", basePath);
}catch(URISyntaxException ex){
//log the error
}
}
public static void main(String args []){
//Your app logic
//All these approaches should return the expected value
//regardless of the way the jar is executed.
String userDirectory = System.getProperty("user.dir");
String userDirectory2 = new File("").getAbsolutePath();
String userDirectory3 = Paths.get("").toAbsolutePath().toString();
}
}
Я надеюсь, что это объяснение и подробности будут полезны другим...
Это моя серебряная пуля, когда наступает момент замешательства.(Назовите это первым делом в main). Может быть, например, JVM подсунут в другую версию IDE. Эта статическая функция ищет PID текущего процесса и открывает VisualVM на этом pid. Путаница здесь останавливается, потому что вы хотите всего этого и получаете это...
public static void callJVisualVM() {
System.out.println("USER:DIR!:" + System.getProperty("user.dir"));
//next search current jdk/jre
String jre_root = null;
String start = "vir";
try {
java.lang.management.RuntimeMXBean runtime =
java.lang.management.ManagementFactory.getRuntimeMXBean();
String jvmName = runtime.getName();
System.out.println("JVM Name = " + jvmName);
long pid = Long.valueOf(jvmName.split("@")[0]);
System.out.println("JVM PID = " + pid);
Runtime thisRun = Runtime.getRuntime();
jre_root = System.getProperty("java.home");
System.out.println("jre_root:" + jre_root);
start = jre_root.concat("\\..\\bin\\jvisualvm.exe " + "--openpid " + pid);
thisRun.exec(start);
} catch (Exception e) {
System.getProperties().list(System.out);
e.printStackTrace();
}
}
Попробуйте что-то вроде этого Я знаю, что опаздываю на ответ, но эта очевидная вещь произошла в java8, новой версии, откуда этот вопрос задается, но ...
Код
import java.io.File;
public class Find_this_dir {
public static void main(String[] args) {
//some sort of a bug in java path is correct but file dose not exist
File this_dir = new File("");
//but these both commands work too to get current dir
// File this_dir_2 = new File(this_dir.getAbsolutePath());
File this_dir_2 = new File(new File("").getAbsolutePath());
System.out.println("new File(" + "\"\"" + ")");
System.out.println(this_dir.getAbsolutePath());
System.out.println(this_dir.exists());
System.out.println("");
System.out.println("new File(" + "new File(" + "\"\"" + ").getAbsolutePath()" + ")");
System.out.println(this_dir_2.getAbsolutePath());
System.out.println(this_dir_2.exists());
}
}
Это сработает и покажет вам текущий путь, но я сейчас не понимаю, почему java не может найти текущий каталог в
new File("");
кроме того, я использую компилятор Java8 ...
Это работает отлично, я даже тестировал
new File(new File("").getAbsolutePath());
Теперь у вас есть текущий каталог в объекте File, поэтому (пример файлового объекта - f),
f.getAbsolutePath()
предоставит вам путь в виде переменной String ...
Протестировано в другом каталоге, отличном от диска C, работает нормально
Вы можете использовать
new File("./")
. Сюда
isDirectory()
возвращает true (по крайней мере, на платформе Windows). С другой стороны
new File("") isDirectory()
возвращает ложь.
Не совсем уверен, чего вы пытаетесь достичь, но приведенные выше ответы работают с текущим рабочим каталогом, из которого вы спрашиваете, а не из того места, где на самом деле находится программа.
Например:
$> mkdir -p /tmp/paths/check
$> cat > /tmp/paths/check/GetPath.java
import java.nio.file.Paths;
import java.nio.file.FileSystems;
public class GetPath {
// Note: these methods work slightly differently, the last two will provide the working dir
// for where this program was launched, while the first will get the cwd from where this
// program resides.
public static void main(String[] args) {
String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
System.out.println("Thread rootPath is "+rootPath);
System.out.println("System property user.dir is "+System.getProperty("user.dir"));
System.out.println("NIO Paths way is "+Paths.get("").toAbsolutePath());
System.out.println("NIO FileSystems way is "+FileSystems.getDefault().getPath("").toAbsolutePath());
}
}
Затем, если вы запустите его из /tmp, вы увидите:
$> cd /tmp/paths/check; javac GetPath.java
$> cd /tmp
$> java -cp paths/check GetPath
Thread rootPath is /tmp/paths/check/
system property user.dir is /tmp
NIO Paths way is/tmp
NIO FileSystems way is/tmp
Итак, первый способ с использованием
Это не совсем то, о чем спрашивают, но вот важное замечание: при запуске Java на компьютере с Windows установщик Oracle помещает "java.exe" в C:\Windows\system32, и это то, что действует как средство запуска для Приложение Java (ЕСЛИ в PATH ранее не было java.exe и приложение Java запускалось из командной строки). Вот почему File(".") Продолжает возвращать C:\Windows\system32, и почему запускаемые примеры из реализаций macOS или *nix продолжают возвращаться с разными результатами из Windows.
К сожалению, на самом деле нет универсально правильного ответа на этот вопрос, насколько я обнаружил за двадцать лет программирования на Java, если только вы не хотите создать свой собственный исполняемый файл запуска с помощью JNI Invocation и получить текущий рабочий каталог из собственного кода запуска, когда он запущен. Все остальное будет иметь хоть какой-то нюанс, который может сломаться в определенных ситуациях.
Мой любимый метод - получить его из переменных среды System, прикрепленных к текущему запущенному процессу, в этом случае ваше приложение управляется JVM.
String currentDir = System.getenv("PWD");
/*
/home/$User/Documents/java
*/
Чтобы просмотреть другие переменные среды, которые могут оказаться полезными, например, домашний каталог, версия ОС ........
//Home directory
String HomeDir = System.getEnv("HOME");
//Outputs for unix
/home/$USER
//Device user
String user = System.getEnv("USERNAME");
//Outputs for unix
$USER
Прекрасная вещь в этом подходе заключается в том, что все пути будут разрешены для всех типов платформ ОС.
Ни один из ответов, опубликованных здесь, не работал для меня. Вот что сработало:
java.nio.file.Paths.get(
getClass().getProtectionDomain().getCodeSource().getLocation().toURI()
);
Изменить: окончательная версия в моем коде:
URL myURL = getClass().getProtectionDomain().getCodeSource().getLocation();
java.net.URI myURI = null;
try {
myURI = myURL.toURI();
} catch (URISyntaxException e1)
{}
return java.nio.file.Paths.get(myURI).toFile().toString()
Это имя текущего каталога
String path="/home/prasad/Desktop/folderName";
File folder = new File(path);
String folderName=folder.getAbsoluteFile().getName();
это текущий путь к каталогу
String path=folder.getPath();