Как получить текущий рабочий каталог в Java?

112

Допустим, у меня есть основной класс C:\Users\Justian\Documents\. Как я могу заставить мою программу показать, что она есть C:\Users\Justian\Documents?

Жесткое кодирование не является вариантом - его нужно адаптировать, если оно перемещено в другое место.

Я хочу сбросить кучу файлов CSV в папку, чтобы программа распознала все файлы, а затем загрузила данные и манипулировала ими. Я действительно просто хочу знать, как перейти к этой папке.

Юстиан Мейер
источник
1
взгляните на эту статью .
Мэтью Дж. Моррисон,
1
Что, если ваш основной класс находится в файле jar? Какого же результата вы хотели бы тогда?
Маттиас Нильссон
1
Зачем вообще это нужно делать?
Эд С.
1
похоже, что вам нужен каталог, в котором находятся файлы CSV, и пусть файл .jar может ссылаться на этот каталог, см. мой ответ, если это так.

Ответы:

149

Один из способов - использовать системное свойство, System.getProperty("user.dir"); которое даст вам «Текущий рабочий каталог на момент инициализации свойств». Наверное, это то, что вам нужно. чтобы узнать, где javaбыла введена команда, в вашем случае в каталоге с файлами для обработки, даже если фактический файл .jar может находиться где-то еще на машине. Наличие каталога фактического файла .jar в большинстве случаев не так полезно.

Ниже будет распечатан текущий каталог, из которого была вызвана команда, независимо от того, где находится файл .class или .jar, в котором находится файл .class.

public class Test
{
    public static void main(final String[] args)
    {
        final String dir = System.getProperty("user.dir");
        System.out.println("current dir = " + dir);
    }
}  

если вы находитесь в /User/me/и ваш файл .jar, содержащий приведенный выше код, будет выведен /opt/some/nested/dir/ командой .java -jar /opt/some/nested/dir/test.jar Testcurrent dir = /User/me

Вы также должны в качестве бонуса взглянуть на использование хорошего объектно-ориентированного парсера аргументов командной строки. Я настоятельно рекомендую JSAP , Java Simple Argument Parser. Это позволит вам использовать System.getProperty("user.dir")и, в качестве альтернативы, передать что-то еще, чтобы переопределить поведение. Гораздо более удобное в обслуживании решение. Это упростит передачу в каталог для обработки и позволит вернуться к работе, user.dirесли ничего не было передано.


источник
Я проверю это, когда смогу. Я действительно озабочен этой проблемой .jar: P
Юстиан Мейер
Вы посещали ссылку в моем ответе на эту проблему .jar, где я показываю, как создать файл .jar с помощью ANT?
Код от Jarrod, который возвращает абсолютный путь к текущему рабочему каталогу из System Property user.dir, очень прост в использовании. System.getProperty ("user.dir");
74

Использовать 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());
    }
}

Обновление в соответствии с комментарием OP:

Я хочу сбросить кучу файлов CSV в папку, чтобы программа распознала все файлы, а затем загрузила данные и манипулировала ими. Я действительно просто хочу знать, как перейти к этой папке.

Для этого потребуется жесткое кодирование / знание их относительного пути в вашей программе. Лучше подумайте о добавлении его пути в путь к классам, чтобы вы могли использоватьClassLoader#getResource()

File classpathRoot = new File(classLoader.getResource("").getPath());
File[] csvFiles = classpathRoot.listFiles(new FilenameFilter() {
    @Override public boolean accept(File dir, String name) {
        return name.endsWith(".csv");
    }
});

Или пройти свой путь как main() аргумента.

BalusC
источник
3
+1. Есть несколько условий, чтобы заставить эту работу работать; наиболее важным является то, что ваш «основной класс» загружается из файловой системы. В Java это предположение не является чем-то необычным. Но, если вы уверены , что вы загружаете свой класс из JAR файла в файловой системе, это метод , который работает.
erickson
На самом деле все зависит от обстоятельств. Я пытаюсь скомпилировать свой JAR, но на данный момент это отдельная проблема. Если вы думаете, что можете помочь с этим, посетите: stackoverflow.com/questions/3152240/… . Я уверен, что публикация этого сообщения является неким нарушением, но это связано с этой проблемой. Если я смогу это исправить, это наверняка будет моим ответом.
Justian Meyer
Зачем мне это жестко кодировать? Я делал подобное раньше. Предположим, что моя банка и папка всегда будут иметь одинаковые отношения (т. Е. В одном каталоге). Если бы это было правдой, я мог бы получить каталог банки, а затем изменить его, чтобы найти папку.
Justian Meyer
Если он находится в той же папке, что и JAR-файл, значит, он уже находится в пути к классам. Слово «жесткое кодирование» немного преувеличено, на самом деле я имел в виду «знание их пути относительно файла JAR».
BalusC
1
@ Мебиус: А? Вы новичок в Java? Проверьте javadoc . Просто используйте именно тот, который возвращается getLocation()методом. Остальные явно не сработают.
BalusC 01
31
File currentDirectory = new File(new File(".").getAbsolutePath());
System.out.println(currentDirectory.getCanonicalPath());
System.out.println(currentDirectory.getAbsolutePath());

Печатает что-то вроде:

/path/to/current/directory
/path/to/current/directory/.

Обратите внимание, что File.getCanonicalPath()выдает проверенное исключение IOException, но удаляет такие вещи, как ../../../

кибер-монах
источник
13
this.getClass().getClassLoader().getResource("").getPath()
Питер Де Винтер
источник
обратите внимание, что это вернет путь к «bin / classes /», а не только к «bin».
разработчик Android
при отладке работающего приложения с использованием Intellij Idea это возвращало "/C:/Program%20Files/Java/jdk1.8.0_112/:"
скорость
5

Я просто использовал:

import java.nio.file.Path;
import java.nio.file.Paths;

...

Path workingDirectory=Paths.get(".").toAbsolutePath();
user3696181
источник
9
Твое не работает, это правильноPaths.get("").toAbsolutePath();
К Кра
@ToKra Если я Paths.get("my/file").toAbsolutePath()получу /my/file, то это точно не cwd.
abergmeier 08
1
@abergmeier Я написал "" в строке, а не "my / file"
To Kra
5

Если вы хотите получить текущий рабочий каталог, используйте следующую строку

System.out.println(new File("").getAbsolutePath());
Рджраджсаха
источник
4

Если вам нужен абсолютный путь к текущему исходному коду, мое предложение:

String internalPath = this.getClass().getName().replace(".", File.separator);
String externalPath = System.getProperty("user.dir")+File.separator+"src";
String workDir = externalPath+File.separator+internalPath.substring(0, internalPath.lastIndexOf(File.separator));
джмамато
источник
Это не работает, когда вы запускаете его в среде IDE или используете что-то для вращения экземпляра.
Сарп Кая
Внутренний путь - java \ lang \ Class. Внешний путь - E: \ BranchProduction1.4.0 \ FilesTestProject \ src. Рабочий каталог - E: \ BranchProduction1.4.0 \ FilesTestProject \ src \ java \ lang, не могли бы вы объяснить результат?
JAVA
3

Кто сказал, что ваш основной класс находится в файле на локальном жестком диске? Классы чаще объединяются в файлы JAR, а иногда загружаются по сети или даже генерируются на лету.

Так что же вы на самом деле хотите делать? Вероятно, есть способ сделать это, не делая предположений о происхождении классов.

Майкл Боргвардт
источник
Я хочу сбросить кучу файлов CSV в папку, чтобы программа распознала все файлы, а затем загрузила данные и манипулировала ими. Я действительно просто хочу знать, как перейти к этой папке.
Justian Meyer
Может быть, я что-то упускаю, но похоже, что абсолютный путь подойдет. Вы сказали, что не можете его жестко запрограммировать, но как вы узнаете, в какую папку искать для начала?
Крис Томпсон,
Проблема в том, что я хочу перенести его на другие компьютеры, а не только на свой. Я не вижу, как будет работать жесткое кодирование пути. «Предположим, что моя банка и папка всегда будут иметь одинаковые отношения (т. Е. В одном каталоге). Если бы это было так, я мог бы получить каталог банки, а затем изменить его, чтобы найти папку». Единственный способ, которым я мог бы жестко закодировать это, - это если бы мне не нужно было включать полный путь от жесткого диска к файлу. Может быть, я смогу вернуться назад всего на 3 папки (например, «Документы \ Проект \ Дамп \ [файл / папка]»)
Юстиан Мейер
Я бы сказал, что вы хотите получить дескриптор каталога, в котором находится файл jar. Отвечает ли это вашим требованиям?
Крис Томпсон,