Jak uzyskać aktualny katalog roboczy w Javie?


112

Powiedzmy, że mam swoją główną klasę C:\Users\Justian\Documents\. Jak mogę sprawić, by mój program pokazał, że jest dostępny C:\Users\Justian\Documents?

Hard-Coding nie wchodzi w grę - musi być przystosowalne, jeśli zostanie przeniesione w inne miejsce.

Chcę zrzucić kilka plików CSV do folderu, poprosić program o rozpoznanie wszystkich plików, a następnie załadować dane i manipulować nimi. Naprawdę chcę tylko wiedzieć, jak przejść do tego folderu.



1
A co jeśli twoja główna klasa znajduje się w pliku jar? Jakiego wyniku chciałbyś wtedy?
Mattias Nilsson

1
Dlaczego w ogóle miałbyś to robić?
Ed S.

1
brzmi tak, jakbyś potrzebował katalogu, w którym znajdują się pliki CSV, i niech plik .jar będzie mógł odwoływać się do tego katalogu, zobacz moją odpowiedź, jeśli tak jest.

Odpowiedzi:


149

Jednym ze sposobów byłoby użycie właściwości systemowej, System.getProperty("user.dir"); która da ci „Bieżący katalog roboczy, kiedy właściwości zostały zainicjowane”. Prawdopodobnie tego chcesz. aby dowiedzieć się, gdzie javapolecenie zostało wydane, w twoim przypadku w katalogu z plikami do przetworzenia, nawet jeśli rzeczywisty plik .jar może znajdować się gdzie indziej na komputerze. Posiadanie katalogu z rzeczywistym plikiem .jar nie jest przydatne w większości przypadków.

Poniższe polecenia wydrukują bieżący katalog, z którego polecenie zostało wywołane, niezależnie od tego, gdzie znajduje się plik .class lub .jar, w którym znajduje się plik .class.

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

jeśli jesteś w programie, /User/me/a plik .jar zawierający powyższy kod jest w /opt/some/nested/dir/ poleceniu java -jar /opt/some/nested/dir/test.jar Test, wyświetli się current dir = /User/me.

Jako bonus powinieneś również przyjrzeć się używaniu dobrego obiektowego parsera argumentów wiersza poleceń. Bardzo polecam JSAP , Java Simple Argument Parser. Umożliwiłoby to użycie System.getProperty("user.dir")i alternatywnie przekazanie czegoś innego, aby zastąpić to zachowanie. O wiele łatwiejsze w utrzymaniu rozwiązanie. To sprawiłoby, że przekazywanie do katalogu w celu przetworzenia byłoby bardzo łatwe do wykonania i user.dirgdyby nic nie zostało przekazane , można by do niego wrócić .


Przetestuję to, kiedy będę mógł. Jestem naprawdę zajęty tym problemem .jar: P
Justian Meyer

czy odwiedziłeś link w mojej odpowiedzi na ten problem .jar, gdzie pokazuję, jak zbudować plik .jar za pomocą ANT?

Kod z Jarroda, który zwraca bezwzględną ścieżkę bieżącego katalogu roboczego z właściwości systemu, user.dirjest bardzo łatwy w użyciu. System.getProperty ("user.dir");

74

Użyj CodeSource#getLocation(). Działa to również dobrze w plikach JAR. Możesz uzyskać CodeSourceprzez, ProtectionDomain#getCodeSource()a z ProtectionDomainkolei można uzyskać przez 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());
    }
}

Aktualizacja zgodnie z komentarzem PO:

Chcę zrzucić kilka plików CSV do folderu, poprosić program o rozpoznanie wszystkich plików, a następnie załadować dane i manipulować nimi. Naprawdę chcę tylko wiedzieć, jak przejść do tego folderu.

Wymagałoby to zakodowania / znajomości ich względnej ścieżki w programie. Zamiast tego rozważ dodanie jego ścieżki do ścieżki klas, aby można było użyć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");
    }
});

Lub przekazać swoją ścieżkę jako main()argument.


3
+1. Jest kilka warunków, aby to zadziałało; najważniejsze jest to, że twoja "główna klasa" jest ładowana z systemu plików. W Javie nie jest niczym niezwykłym, że to założenie jest fałszywe. Ale, jeśli jesteś pewien, że ładujesz swoją klasę z słoik na systemie plików, to metoda, która działa.
erickson

Tak naprawdę wszystko zależy. Ja próbuje dostać mój JAR skompilować, ale to osobny problem w tej chwili. Jeśli uważasz, że możesz w tym pomóc, odwiedź: stackoverflow.com/questions/3152240/… . Jestem pewien, że opublikowanie tego jest wykroczeniem, ale ma to związek z tym problemem. Jeśli uda mi się to naprawić, na pewno będzie to moja odpowiedź.
Justian Meyer

Dlaczego miałbym to zakodować? Robiłem już podobne rzeczy. Załóżmy, że mój jar i folder zawsze będą miały podobną relację (tj. W tym samym katalogu). Jeśli to prawda, mógłbym uzyskać katalog jar, a następnie zmodyfikować go, aby znaleźć folder.
Justian Meyer

Jeśli znajduje się w tym samym folderze, co plik JAR, oznacza to, że jest już w ścieżce klas. Słowo „kodowanie na stałe” jest nieco przesadzone, tak naprawdę miałem na myśli „znajomość ich ścieżki w stosunku do pliku JAR”.
BalusC

1
@Moebius: Hę? Czy jesteś nowy w Javie? Sprawdź javadoc . Po prostu użyj dokładnie tego, co zwrócone przez getLocation()metodę. Inne oczywiście nie będą działać.
BalusC

31
File currentDirectory = new File(new File(".").getAbsolutePath());
System.out.println(currentDirectory.getCanonicalPath());
System.out.println(currentDirectory.getAbsolutePath());

Drukuje coś takiego:

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

Zwróć uwagę, że File.getCanonicalPath()zgłasza sprawdzony IOException, ale usunie takie rzeczy, jak ../../../


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

zwróć uwagę, że zwróci to ścieżkę do „bin / classes /”, a nie tylko do „bin”.
programista Androida

podczas debugowania działającej aplikacji przy użyciu Intellij Idea, zwróciło to „/C:/Program%20Files/Java/jdk1.8.0_112/:”
prędkość

5

Właśnie użyłem:

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

...

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

9
Twój nie działa, to jest poprawnePaths.get("").toAbsolutePath();
To Kra

@ ToKra Jeśli Paths.get("my/file").toAbsolutePath()dostanę /my/file, co na pewno nie jest cwd.
abergmeier

1
@abergmeier Napisałem „” w ciągu znaków, a nie „mój / plik”
do Kra

5

Jeśli chcesz uzyskać bieżący katalog roboczy, użyj następującego wiersza

System.out.println(new File("").getAbsolutePath());

4

Jeśli chcesz mieć bezwzględną ścieżkę obecnego kodu źródłowego, moja sugestia jest taka:

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

To nie działa, gdy uruchamiasz go w IDE lub używasz czegoś do obracania instancji.
Sarp Kaya,

Ścieżka wewnętrzna to java \ lang \ Class Ścieżka zewnętrzna to E: \ BranchProduction1.4.0 \ FilesTestProject \ src Katalog roboczy to E: \ BranchProduction1.4.0 \ FilesTestProject \ src \ java \ lang czy możesz wyjaśnić wynik?
JAVA

3

Kto powiedział, że twoja główna klasa jest w pliku na lokalnym dysku twardym? Klasy są częściej umieszczane w plikach JAR i czasami ładowane przez sieć, a nawet generowane w locie.

Więc co tak naprawdę chcesz robić? Prawdopodobnie istnieje sposób, aby to zrobić, który nie zakłada założeń, skąd pochodzą klasy.


Chcę zrzucić kilka plików CSV do folderu, poprosić program o rozpoznanie wszystkich plików, a następnie załadować dane i manipulować nimi. Naprawdę chcę tylko wiedzieć, jak przejść do tego folderu.
Justian Meyer

Może czegoś mi brakuje, ale wygląda na to, że absolutna ścieżka zadziała. Powiedziałeś, że nie możesz tego na stałe zakodować, ale skąd masz wiedzieć, w którym folderze zajrzeć na początek?
Chris Thompson,

Problem w tym, że chcę go przenieść na inne komputery, nie tylko na swój własny. Nie rozumiem, jak twarde kodowanie ścieżki mogłoby działać. „Załóżmy, że mój jar i folder zawsze będą miały podobną relację (tj. W tym samym katalogu). Gdyby to było prawdą, mógłbym uzyskać katalog jar, a następnie zmodyfikować go, aby znaleźć folder”. Jedyny sposób, w jaki mógłbym go zakodować, to gdybym nie musiał uwzględniać pełnej ścieżki z dysku twardego do pliku. Może uda mi się cofnąć tylko 3 foldery (tj. „Dokumenty \ Projekt \ Zrzut \ [plik / folder]”)
Justian Meyer

Powiedziałbym, że chcesz uzyskać uchwyt do katalogu, w którym znajduje się plik jar. Czy spełniłoby to Twoje wymagania?
Chris Thompson,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.