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


112

Скажімо, в мене головний клас C:\Users\Justian\Documents\. Як я можу змусити свою програму показати, що вона є C:\Users\Justian\Documents?

Hard-Coding - це не варіант - він повинен бути адаптованим, якщо він переміщений в інше місце.

Я хочу скинути купу файлів CSV у папку, запропонувати програмі розпізнати всі файли, а потім завантажити дані та ними маніпулювати. Мені просто хочеться знати, як перейти до цієї папки.



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 Testвихід буде current dir = /User/me.

Ви також повинні як бонус розглянути використання хорошого аналізатора аргументів командного рядка, орієнтованого на об'єкт. Я настійно рекомендую JSAP , Java Simple Argument Parser. Це дозволить вам скористатися System.getProperty("user.dir")і, можливо, передати щось інше, щоб надмірно їздити на поведінку. Набагато рентабельніше рішення. Це зробило б проходження в каталозі обробляти дуже просто, і мати можливість повернутися назад, user.dirякщо нічого не було передано.


Я перевірю це, коли зможу. Я справді зайнятий цим питанням .jar: P
— Justian Meyer

Ви зайшли за посиланням у моїй відповіді на це питання .jar, де я показав, як створити файл .jar з ANT?

Код від Jarrod, який повертає поточному робочому каталогу абсолютний шлях від System Properties 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());
    }
}

Оновлення відповідно до коментаря ОП:

Я хочу скинути купу файлів CSV у папку, запропонувати програмі розпізнати всі файли, а потім завантажити дані та ними маніпулювати. Мені просто хочеться знати, як перейти до цієї папки.

Це вимагатиме жорсткого кодування / знання їх відносного шляху у вашій програмі. Швидше подумайте, як додати його шлях до classpath, щоб можна було використовувати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()аргумент.


3
+1. Існує кілька умов, щоб зробити цю роботу; найголовніше - ваш "основний клас" завантажується з файлової системи. У Java не так страшно незвично, що це припущення є помилковим. Але, якщо ви впевнені , що ви завантажуєте свій клас з JAR файлу в файлової системі, це метод , який працює.
— еріксон

Все залежить, насправді. Я намагаюся зробити свій JAR для складання, але це наразі окреме питання. Якщо ви думаєте, що можете допомогти у цьому, перевірте: stackoverflow.com/questions/3152240/… . Я впевнений, що розміщення цього повідомлення є певним порушенням, але це пов'язано з цим питанням. Якщо я можу це виправити, це, безумовно, буде моєю відповіддю.
— Градіан Мейєр

Навіщо мені це потрібно жорстко кодувати? Я робив подібні речі і раніше. Припустимо, що мій jar та папка завжди матимуть подібні стосунки (тобто в одному каталозі). Якщо це було правдою, я міг би отримати каталог jar, а потім змінити його, щоб знайти папку.
— Justian Meyer

Якщо він знаходиться в тій самій папці, що і файл JAR, то він просто вже знаходиться в класі. Слово "жорстке кодування" трохи перебільшене, я насправді мав на увазі "знати їх шлях відносно файлу JAR".
— BalusC

1
@Moebius: Так? Ви новачок у Java? Перевірте javadoc . Просто використовуйте саме той, який повертається getLocation()методом. Інші, очевидно, не збираються працювати.
— BalusC

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, але він видалить такі речі ../../../



5

Я щойно використовував:

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

...

Path workingDirectory=Paths.get(".").toAbsolutePath();

9
Твоє не працює, це одне правильноPaths.get("").toAbsolutePath();
— до

@ToKra Якщо я Paths.get("my/file").toAbsolutePath()отримаю /my/file, це точно не є cwd.
— abergmeier

1
@abergmeier Я написав "" в рядку не "мій / файл"
— До

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 або використовуєте щось для відтворення екземпляра.
— Sarp Kaya

Внутрішній шлях - java \ lang \ Class Зовнішній шлях - це E: \ BranchProduction1.4.0 \ FilesTestProject \ src Робочий каталог - це E: \ BranchProduction1.4.0 \ FilesTestProject \ src \ java \ lang, чи можете ви пояснити вихід?
— JAVA

3

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

То що ж ви насправді хочете зробити? Ймовірно, існує спосіб, який не робить припущень щодо того, звідки беруться заняття.


Я хочу скинути купу файлів CSV у папку, запропонувати програмі розпізнати всі файли, а потім завантажити дані та ними маніпулювати. Мені просто хочеться знати, як перейти до цієї папки.
— Градіан Мейєр

Можливо, мені чогось не вистачає, але здається, що абсолютний шлях спрацював би. Ви сказали, що не можете його жорстко закодувати, але як ви дізнаєтесь, з якої папки слід заглянути?
— Кріс Томпсон

Ну, проблема полягає в тому, що я хочу перенести це на інші комп'ютери, а не тільки на свій власний. Я не бачу, як жорстке кодування буде працювати. "Припустимо, що мій jar та папка завжди матимуть подібні стосунки (тобто в одному каталозі). Якщо це було правдою, я міг би отримати каталог jar, а потім змінити його, щоб знайти папку." Єдиним способом я міг би це зробити жорстким кодом, якби мені не довелося включати повний шлях від жорсткого диска до файлу. Можливо, я можу повернути лише 3 папки назад (тобто "Документи \ Проект \ Дамп \ [файл / папка]")
— Justian Meyer

Я б сказав, що ви хочете зробити, це отримати ручку до каталогу, в якому знаходиться файл jar. Чи це би відповідало вашим вимогам?
— Кріс Томпсон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.