Получение текущего рабочего каталога в 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();

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

File currentDir = new File("");

Что заставляет вас думать, что 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());
    }
}
this.getClass().getClassLoader().getResource("").getPath()

Как правило, как объект File:

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

Вы можете захотеть иметь полную квалифицированную строку, например, "D:/a/b/c", выполнив

getCwd().getAbsolutePath()

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

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

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

Paths.get("") документы

System.getProperty("user.dir") документы

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

Лучший,

Это очень запутанная тема, и нам нужно понять некоторые концепции, прежде чем предлагать реальное решение.

  1. Файл и NIO File Api подходят с относительными путями""или"."использует внутренне значение системного параметра для определения места возврата.

  2. The "user.dir" значение основано на рабочем каталоге USER, и поведение этого значения зависит от операционной системы и способа выполнения jar.

  3. Например, выполнение 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()

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

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

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

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

String path=folder.getPath();
Другие вопросы по тегам