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.