Получение текущего рабочего каталога в Java

716

Я хочу получить доступ к текущему рабочему каталогу, используя

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

OutPut:

Current dir: C:\WINDOWS\system32
Current dir using System: C:\WINDOWS\system32

Мой вывод неверен, потому что диск C не является моим текущим каталогом. Нужна помощь в этом отношении.

  • 0
    Вы можете вставить сюда то, что вы видите, когда вы выполняете команду cd в командной строке, когда вы выполняете это?
  • 2
    Чего вы пытаетесь достичь, обращаясь к рабочему каталогу? Можно ли это сделать, используя вместо этого путь к классу? Например, если вам нужно прочитать текстовый файл в файловой системе, вы можете легко найти его, когда он находится в пути к классам.
Показать ещё 6 комментариев
Теги:
working-directory

19 ответов

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

Здесь будет напечатан полный абсолютный путь , от которого было инициализировано ваше приложение.

  • 24
    @ubuntudroid: именно поэтому я упомянул, что он напечатает путь, с которого инициализировалось приложение. Полагаю, что запуск потока непосредственно запускает jar / программу после запуска приглашения commnad (которое в основном находится в C: \ WINDOWS \ system32). Я надеюсь, вы понимаете мою точку зрения. Предполагая, что вы проголосовали, оцените, что, по крайней мере, вы хотели оставить отзыв. :)
  • 1
    user.dir получит путь к папке, в которой запущен процесс. Чтобы узнать фактический путь к главной папке приложения, смотрите мой ответ ниже.
Показать ещё 8 комментариев
283

Смотрите: 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
    Первый не проверен, но второй фактически получит вашу домашнюю папку. Не текущий рабочий каталог, в котором запущено приложение.
  • 10
    Пожалуйста, не путайте домашний каталог пользователя ("user.home", / Users / george в вашем случае) и текущий рабочий каталог ("user.dir", который будет каталогом, из которого вы запустили JVM для вашего приложения). , поэтому может быть что-то вроде, например / Users / george / workspace / FooBarProject).
Показать ещё 1 комментарий
163

Ниже описаны работы на Java 7 и выше (см. здесь для документации).

import java.nio.file.Paths;

Paths.get(".").toAbsolutePath().normalize().toString();
  • 8
    Как это лучше, чем более портативный import java.io.File; File(".").getAbsolutePath() ?
  • 5
    Когда вы говорите «портативный», вы имеете в виду, что он работает в Java 6 и более ранних версиях? Paths.get() может считаться лучшим в том Paths.get() что он предоставляет прямой доступ к более мощному интерфейсу Path .
Показать ещё 2 комментария
27

Что заставляет вас думать, что c:\windows\system32 не является вашим текущим каталогом? Свойство user.dir явно является "текущим рабочим каталогом пользователя".

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

Изменить: похоже, что это верно только для старых окон и/или версий Java.

  • 1
    Это не похоже на правду, по крайней мере, на моем компьютере с Windows 7, использующим Java 7. user.dir - это папка, в которой я дважды щелкнул файл jar.
  • 0
    см. ответ stackoverflow.com/a/28149916/1005652
25

Это решение для меня

File currentDir = new File("");
  • 0
    Это имеет побочные эффекты, когда вы используете такой объект File как родительский для другого File: new File (new File (""), "subdir") не будет работать должным образом
  • 11
    Чтобы это исправить, используйте вместо этого new File("").getAbsoluteFile() .
Показать ещё 2 комментария
19

Используйте 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. Не то, что просили.
19
this.getClass().getClassLoader().getResource("").getPath()
  • 12
    Выдает NPE, когда я запускаю свое приложение из файла JAR, дважды щелкнув по нему.
  • 1
    Это также не работает в статическом контексте
Показать ещё 2 комментария
16

обычно, как объект File:

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

вам может потребоваться полная строка, например "D:/a/b/c":

getCwd().getAbsolutePath()
  • 1
    Это хорошо работает в тестах Android, так как Android не содержит java.nio.file.Files.
  • 0
    Кажется, не работает для меня в статическом контексте (новый File ("") генерирует исключение NullPointerException) ..?
Показать ещё 1 комментарий
11

Я нахожусь в Linux и получаю тот же результат для обоих этих подходов:

@Test
public void aaa()
{
    System.err.println(Paths.get("").toAbsolutePath().toString());

    System.err.println(System.getProperty("user.dir"));
}

Paths.get("") docs

System.getProperty("user.dir") docs

3

Это даст вам путь к вашему рабочему каталогу:

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

И это даст вам путь к файлу с именем "Foo.txt" в рабочем каталоге:

Path path = FileSystems.getDefault().getPath("Foo.txt");
  • 7
    это просто возвращает "." для меня.
  • 2
    Да, во многих системах это будет ссылка на рабочий каталог. Чтобы получить абсолютный путь, вы можете добавить еще один вызов метода Path path = FileSystems.getDefault().getPath(".").toAbsolutePath();
Показать ещё 1 комментарий
3

Использование Windows user.dir возвращает каталог, как ожидалось, но НЕ, когда вы запускаете приложение с повышенными правами (запускаетесь как admin), в этом случае вы получаете C:\WINDOWS\system32

3

Надеюсь, вы хотите получить доступ к текущему каталогу, включая пакет i.e. Если ваша программа 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. classpath указывается в командной строке, и «текущий каталог, включающий пакет» (??): a. указано первым, б. указано абсолютно, c. точно соответствует CWD (даже с учетом регистра Windows), и d. потомок CWD
  • 0
    Это относится к пунктам 1 и 2. Но если я что-то упускаю, вы все еще полагаетесь на путь к классу, указанный в командной строке (т.е. не в переменной окружения), и на «текущий каталог, включающий пакет» (я признайся, я не совсем понимаю, что ты имеешь в виду под этим) быть потомком именно первого элемента в classpath. И проблема соответствия случая остается. Извините, если мой комментарий не помог; Я пожертвовал ясностью, чтобы не превышать ограничения на количество комментариев.
Показать ещё 2 комментария
3

Текущий рабочий каталог определяется по-разному в разных реализациях Java. Для определенной версии до Java 7 не было последовательного способа получить рабочий каталог. Вы можете обойти это, запустив файл Java с помощью -D и определяя переменную для хранения информации

Что-то вроде

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

Это не совсем правильно, но вы поняли эту идею. Тогда System.getProperty("com.mycompany.workingDir")...

  • 5
    Не имеет отношения к вопросу.
  • 1
    Это имеет значение для Java - это место на диске, к которому относятся файлы, которые вы открываете с относительными путями.
Показать ещё 1 комментарий
2

Упомяните, что он проверяется только в 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 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;
    }
  • 0
    Это возвращает местоположение файла JAR. Не то, что просили.
  • 0
    @EJP Расположение файла .jar не является текущим рабочим каталогом Java-программы?
2

В Linux, когда вы запустите файл jar из терминала, оба они вернут тот же String: "/home/CurrentUser" , независимо от того, где находится файл jar jar. Это зависит только от того, какой текущий каталог вы используете с вашим терминалом, когда вы запускаете файл jar.

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

System.getProperty("user.dir");

Если ваш Class с main будет называться MainClass, попробуйте:

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

Это вернет String с абсолютным путем файла jar.

  • 2
    Что не то, о чем просили.
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. Не то, что просили.
1

Ни один из ответов, размещенных здесь, не работал у меня. Вот что работало:

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()
  • 0
    см. stackoverflow.com/a/28149916/1005652
  • 0
    Это возвращает местоположение файла JAR. Не то, что просили.
-4

System.getProperty("java.class.path")

-4

это текущее имя каталога

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

это текущий путь к каталогу

String path=folder.getPath();
  • 1
    ОП требовал текущего рабочего каталога, из которого запускалось приложение.
  • 0
    Это ваш домашний каталог, а не текущий рабочий каталог кого-либо, кроме, может быть, вашего. Не то, что просили.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню