Як отримати поточний робочий каталог на Java?


1026

Я хочу отримати доступ до свого поточного робочого каталогу за допомогою 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 - це не моя поточна директорія.

Як отримати поточний каталог?


2
чи можете ви вставити сюди те, що ви бачите, коли ви виконуєте cdкоманду в командному рядку, коли це виконуєте?
Нішант

3
Що ви намагаєтеся досягти, дійшовши до робочого каталогу? Чи можна це зробити, використовуючи натомість шлях до класу? Наприклад, якщо вам потрібно прочитати текстовий файл у файловій системі, його можна легко знайти, коли він знаходиться на шляху до класу.
Earldouglas

1
як? Не могли б ви детальніше розглянути?
C графіка

1
Для деякої інформації про доступ до файлу на шляху до класів, см stackoverflow.com/questions/1464291 / ...
downeyt

7
Для налагодження робочий каталог може бути корисним, щоб дізнатися, чи не здається, що програма не має доступу до існуючих файлів.
nsandersen

Відповіді:


1150
public class JavaApplication {
  public static void main(String[] args) {
       System.out.println("Working Directory = " + System.getProperty("user.dir"));
  }
}

Це дозволить надрукувати повний абсолютний шлях від місця, де ваша програма була ініціалізована.


З документації :

java.ioпакет вирішення відносних імен, використовуючи поточний каталог користувача. Поточний каталог представлений як системне властивість, тобто є user.dirкаталогом, звідки викликався JVM.


25
@ubuntudroid: тому я конкретно згадав, що він буде надрукувати шлях, звідки програма була ініціалізована. Думаю, що запускаючий потік безпосередньо запускає jar / програму після запуску комнатного запиту (що в основному знаходиться на C: \ WINDOWS \ system32). Сподіваюся, ви зрозуміли мою думку. Припускаючи, що ви прихильнилися, оцініть, що принаймні ви піклувались залишити відповідь. :)
Ануй Патель

1
user.dir отримає шлях до папки, в якій був запущений процес. Щоб отримати фактичний шлях до головної папки програми, див. Мою відповідь нижче.
Пітер Де Зима

1
Я маю на увазі "весь код, на який покладається, знайти поточний каталог не вдається." Не весь код взагалі. (Я повинен був повільно відредагувати оригінальний коментар)
SubOptimal

13
@SubOptimal, якщо користувач встановив -Duser.dir, propable, він хоче запустити це у власному робочому каталозі.
barwnikk

5
@indyaah infact ця відповідь неправильна, є тонка різниця між користувачем-робочим каталогом та поточним робочим каталогом системного процесу (cwd); більшість часу "user.dir" вказує на cwd (java) процесу; але "user.dir" має різну семантику і не повинен використовуватися для отримання перебігу процесу java; btw: доступні інші властивості для обробки Java- ja docs.oracle.com/javase/tutorial/essential/environment/… лише для довідки
comeGetSome

381

Дивіться: 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 що в моєму випадку, звідки я запускав клас. Побудова контурів відносно, не використовуючи провідний роздільник для вказівки, що ви будуєте абсолютний шлях, використовуватиме цей відносний шлях як вихідну точку.


2
Перший не перевірився, але другий фактично отримає вашу домашню папку. Не поточний робочий каталог, в якому працює програма.
Пітер Де Зима

12
Будь ласка, не плутайте домашній каталог користувача ("user.home", / Users / george у вашому випадку) та поточний робочий каталог ("user.dir", який буде каталогом, з якого ви запустили JVM для вашої програми , тому може бути щось на зразок / Users / george / робоча область / FooBarProject).
Девід

1
Я вважаю за краще такий спосіб. Коли мені потрібен батько робочого каталогу, це не працює: Paths.get("").getParent()він дає null. Замість цього працює: Paths.get("").toAbsolutePath().getParent().
Оле ВВ

235

Наступні роботи на Java 7 і вище (див. Тут документацію).

import java.nio.file.Paths;

Paths.get(".").toAbsolutePath().normalize().toString();

11
Як це краще, ніж більш портативний import java.io.File; File(".").getAbsolutePath()?
Євгеній Сергєєв

8
Коли ви говорите портативний, ви маєте на увазі, що він працює в Java 6 і раніше? Paths.get()Можна вважати кращим, оскільки він надає прямий доступ до більш потужного Pathінтерфейсу.
Оле ВВ

8
Яка потенційна перевага використання .normalize()в цьому контексті?
Оле ВВ

7
@ OleV.V. З Javadoc: ( нормалізувати метод )Returns a path that is this path with redundant name elements eliminated.
Стефан

У цьому випадку вже буде нормалізовано.
Дж. М. Бекер

73

Це дасть вам шлях до поточного робочого каталогу:

Path path = FileSystems.getDefault().getPath(".");

І це дасть вам шлях до файлу під назвою "Foo.txt" у робочому каталозі:

Path path = FileSystems.getDefault().getPath("Foo.txt");

Редагувати: щоб отримати абсолютний шлях поточного каталогу:

Path path = FileSystems.getDefault().getPath(".").toAbsolutePath();

* Оновити * Щоб отримати поточний робочий каталог:

Path path = FileSystems.getDefault().getPath("").toAbsolutePath();

11
це просто повертається "." для мене.
John ktejik

3
Так, у багатьох системах, які будуть посиланням на робочий каталог. Щоб отримати абсолютний шлях, ви можете додати ще один виклик методуPath path = FileSystems.getDefault().getPath(".").toAbsolutePath();
Марк

2
Вам не потрібен foo.txt, просто покладіть у порожній рядок, щоб отримати каталог
John ktejik

1
У Windows (10) це просто дає мені Pathоб’єкт, що вказує на файл, який називається .всередині поточного робочого режиму. Використання порожнього рядка, а не "."для мене.
Kröw

36

Це рішення для мене

File currentDir = new File("");

1
Це має побічні ефекти, коли ви використовуєте такий об'єкт File як батько іншого файлу: новий файл (новий файл (""), "subdir") не працюватиме, як очікувалося
MRalwasser

13
Щоб виправити це, використовуйте new File("").getAbsoluteFile()замість цього.
MRalwasser

4
Для чого це варто, мені пощастило з File (".").
keshlam

Як визначити відносний шлях у Java Ця сторінка мені допомогла. Також я припускав, що мені слід використовувати /при створенні відносного шляху. Я помилявся, не починайте /. ../також працює для переходу в дерево каталогів.
Irrationalkilla

@keshlam Це дало мені файл у поточному каталозі під назвою ..
Kröw

32

Я знайшов це рішення в коментарях, яке краще, ніж інші, і більш портативне:

String cwd = new File("").getAbsolutePath();

Або навіть

String cwd = Paths.get("").toAbsolutePath();

Це точно так само, як відповідь comeGetSome і насправді Java <7 спосіб
GoGoris

30

Що змушує вас думати, що c: \ windows \ system32 - це не ваш поточний каталог? Theuser.dirВластивість явно бути «поточний робочий каталог користувача».

Якщо говорити іншим способом, якщо ви не запускаєте Java з командного рядка, c: \ windows \ system32, ймовірно, є вашим CWD. Тобто, якщо ви двічі клацніть для запуску програми, CWD навряд чи буде каталогом, з якого ви двічі клацніть.

Редагувати : Схоже, це стосується лише старих версій Windows та / або версій Java.


2
Це, мабуть, не відповідає дійсності, принаймні, не на моїй машині Windows 7, що використовує Java 7. user.dirпослідовно папка, в якій я двічі клацнув файл jar.
Джолта,

26

Використовуйте 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());
    }
}

2
Це повертає розташування файлу JAR. Не те, що просили.
користувач207421

22
this.getClass().getClassLoader().getResource("").getPath()

12
Кидає NPE, коли я запускаю свою програму з файлу JAR, двічі клацнувши її.
Меттью Мудрий

2
Це повертається, ""якщо програма запущена з файлу JAR або елемента CLASSPATH. Не те, що просили.
користувач207421

@ Zizouz212 getClass()- це об'єктний метод, тому в статичному контексті просто видалення thisне працює. Вам доведеться чітко посилатися на клас, у якому ви займаєтесь MyClass.class.getClassLoader()......
Крьов

Тим не менш, він не поверне робочий каталог ...
Angel O'Sphere

18

як об'єкт File:

File getCwd() {
  return new File("").getAbsoluteFile();
}

ви можете мати повний кваліфікований рядок, наприклад "D: / a / b / c", виконуючи такі дії:

getCwd().getAbsolutePath()

1
Це добре працює в тестах Android, оскільки Android не включає java.nio.file.Files.
iamreptar

Здається, це не працює для мене в статичному контексті (новий файл ("") кидає NullPointerException) ..?
nsandersen

2
@nsandersen ви, ймовірно, використовували неправильний об’єкт файлу: System.out.println (новий java.io.File (""). getAbsolutePath ());
comeGetSome


5

У Linux, коли ви запускаєте jar- файл з терміналу , вони обидва повернуть те саме String: "/ home / CurrentUser" , незалежно від того, де ви знаходитесь файл jar. Це залежить лише від того, який поточний каталог ви використовуєте зі своїм терміналом, коли ви запускаєте файл jar.

Paths.get("").toAbsolutePath().toString();

System.getProperty("user.dir");

Якщо ваш Classз mainбуде викликано MainClass, спробуйте:

MainClass.class.getProtectionDomain().getCodeSource().getLocation().getFile();

Це буде повертати Stringз абсолютним шляхом в банку файлу.


3
Що не те, про що просили.
користувач207421

5

Використовуючи Windows, user.dir повертає каталог, як очікувалося, але НЕ, коли ви запускаєте програму з підвищеними правами (запускаєте як адміністратор), у такому випадку ви отримуєте C: \ WINDOWS \ system32


3

Я сподіваюся, що ви хочете отримати доступ до поточного каталогу, включаючи пакет, тобто якщо ваша програма 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.


6
Не було б сумніву не відповідати на цю відповідь. Будь ласка, подумайте більш ретельно перед публікацією. Ваш код порушений, якщо все це не відповідає дійсності: 1. JRE є Oracle, інакше не буде системного властивості "sun.java.command" → NPE; 2. ОС - це Windows (Використовувати File.separatorнатомість або Fileконструктор з багато аргументів ); 3. в командному рядку вказано класний шлях, а "поточний каталог, що включає пакет" (??), є: a. вказаний першим, b. вказано абсолютно, c. точно відповідає CWD (навіть при нечутливості випадку Windows), і d. є нащадком CWD
Майкл Шепер

Це стосується пунктів 1 та 2. Але якщо я чогось не пропускаю, ви все ще покладаєтесь на вказаний в командному рядку класовий шлях (тобто не на змінну середовища) та на "поточний каталог, що включає пакет" (я зізнаюсь, я насправді не розумію, що ти маєш на увазі під собою) бути нащадком конкретно першого елемента в класі. І проблема відповідності випадків залишається. Вибачте, якщо мій коментар не був корисним; Я пожертвував ясністю, щоб залишатися в межах меж символу коментаря.
Майкл Шепер

@Inversus, він лише «ідеально працює» в деяких середовищах; тобі просто пощастило випробувати його в один раз. Написання програмного забезпечення, яке виходить з ладу в законних умовах виконання, не є хорошою практикою, навіть коли ваш набір тестових середовищ недостатньо розширений, щоб включити їх.
Чарльз Даффі

@CharlesDuffy Ви маєте рацію, це не є хорошою практикою. На щастя, це рішення "вирішило [мою] конкретну проблему" не призвело до того, що "[не вдалося] в законних умовах виконання". Насправді, це допомогло мені вирішити таку невдачу і написати більш надійний код, окрім вирішення дуже конкретного питання, яке у мене виникло (яке було лише дещо пов'язане з цим питанням / відповіддю). Напевно, мені просто пощастило знайти.
Інверс

3

Згадайте, що він перевіряється лише в, 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;
    }

Це повертає розташування файлу JAR. Не те, що просили.
користувач207421

@EJP Розташування файлу .jar не є поточним робочим каталогом програми java?
GOXR3PLUS

2

Поточний робочий каталог визначається по-різному в різних реалізаціях Java. Для певної версії до Java 7 не було послідовного способу отримати робочий каталог. Ви могли б обійти це, запустивши файл Java з-D і визначивши змінну для зберігання інформації

Щось на зразок

java -D com.mycompany.workingDir="%0"

Це не зовсім правильно, але ви розумієте. Потім System.getProperty("com.mycompany.workingDir")...


6
Не стосується питання.
Пітер Де Зима

1
Для Java це має значення - це місце на диску, де файли, які ви відкриваєте з відносними іменами шляхів, відносяться до.
Роб І

2
Так, це має сенс. Мої слова були дещо погано обрані. Але ви пропускаєте суть - до Java 7 не було можливості знати поточний робочий каталог, і різні реалізації встановлювали їх ... по-різному ...
MJB

1

припустимо, що ви намагаєтеся запустити свій проект всередині eclipse, або 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

Найкраще,


2
Це повертає розташування файлу JAR. Не те, що просили.
користувач207421

@ user207421 так, я знаю, що ця відповідь не є справжньою відповіддю на питання, але більшість часу всі хочуть отримати "каталог, де розташовані банки", а не "робочий каталог командного рядка".
bachden

0

Жодна з розміщених тут відповідей не працювала на мене. Ось що було:

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()

Це повертає розташування файлу JAR. Не те, що просили.
користувач207421

0

Це моя срібна куля, коли колись мить заплутався. (Назвіть це як головне). Можливо, наприклад, JVM ковзає, щоб бути іншою версією IDE. Ця статична функція здійснює пошук поточного PID процесу та відкриває VisualVM на цьому під. Плутанина там зупиняється, тому що ти хочеш все це і отримуєш ...

  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();
    }
}


-7

це поточна назва каталогу

String path="/home/prasad/Desktop/folderName";
File folder = new File(path);
String folderName=folder.getAbsoluteFile().getName();

це поточний шлях до каталогу

String path=folder.getPath();

1
ОП хотіла, щоб поточний робочий номер, звідки було запущено заявку.
Лейф Грюнвольдт

Це ваш домашній каталог, а не чийсь поточний робочий каталог, крім, можливо, вашого. Не те, що просили.
користувач207421
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.