Bagaimana cara mendapatkan direktori kerja saat ini di Jawa?

1029

Saya ingin mengakses direktori kerja saya saat ini menggunakan java.

Kode saya:

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

Keluaran:

Current dir: C:\WINDOWS\system32
Current dir using System: C:\WINDOWS\system32

Output saya tidak benar karena drive C bukan direktori saya saat ini.

Bagaimana cara mendapatkan direktori saat ini?

Qazi
sumber
2
dapatkah Anda menempel di sini apa yang Anda lihat ketika Anda menjalankan cdperintah pada command-prompt Anda ketika Anda menjalankan ini?
Nishant
3
Apa yang ingin Anda capai dengan mengakses direktori kerja? Bisakah itu dilakukan dengan menggunakan jalur kelas saja? Misalnya, jika Anda perlu membaca file teks pada sistem file, Anda dapat menemukannya dengan mudah ketika berada di jalur kelas.
earldouglas
1
bagaimana? Bisakah Anda menguraikannya?
Grafik C
1
Untuk beberapa informasi tentang mengakses file di jalur kelas, lihat stackoverflow.com/questions/1464291/…
downeyt
7
Untuk keperluan debugging, direktori kerja dapat berguna untuk mengetahui apakah program tersebut tampaknya tidak dapat mengakses file yang ada.
nsandersen

Jawaban:

1152
public class JavaApplication {
  public static void main(String[] args) {
       System.out.println("Working Directory = " + System.getProperty("user.dir"));
  }
}

Ini akan mencetak jalur absolut lengkap dari tempat aplikasi Anda diinisialisasi.


Dari dokumentasi :

java.iopaket menyelesaikan nama path relatif menggunakan direktori pengguna saat ini. Direktori saat ini direpresentasikan sebagai properti sistem, yaitu, user.dirdan merupakan direktori dari mana JVM dipanggil.

Anuj Patel
sumber
25
@ubuntudroid: itu sebabnya saya sebutkan secara spesifik bahwa ia akan mencetak path dari tempat aplikasi diinisialisasi. Saya kira thread starter langsung menjalankan jar / program setelah memulai prompt commnad (yang pada dasarnya di C: \ WINDOWS \ system32). Saya harap Anda mengerti maksud saya. Dengan asumsi Anda downvoted, hargai setidaknya Anda peduli untuk meninggalkan respons. :)
Anuj Patel
1
user.dir akan mendapatkan path ke folder tempat proses diluncurkan. Untuk mendapatkan jalur aktual ke folder utama aplikasi, lihat jawaban saya di bawah ini.
Peter De Winter
1
Maksud saya "semua kode bergantung padanya untuk menemukan direktori saat ini gagal." Tidak semua kode pada umumnya. (Saya lambat untuk mengedit komentar asli)
SubOptimal
13
@ SubOptimal jika pengguna mengatur -Duser.dir, layak dia ingin menjalankan ini di direktori kerja kustom.
barwnikk
5
@ indyaah infact jawaban ini salah, ada perbedaan halus antara direktori pengguna-bekerja dan direktori kerja-saat ini dari proses sistem (cwd); sebagian besar waktu "user.dir" menunjuk ke cwd dari proses (java); tetapi "user.dir" memiliki semantik yang berbeda dan tidak akan digunakan untuk mendapatkan cwd dari proses java; btw: ada lebih banyak properti yang tersedia untuk proses java docs.oracle.com/javase/tutorial/essential/environment/… hanya untuk referensi
comeGetSome
382

Lihat: http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html

Menggunakan java.nio.file.Pathdan java.nio.file.Paths, Anda dapat melakukan hal berikut untuk menunjukkan apa yang menurut Java adalah jalur Anda saat ini. Ini untuk 7 dan seterusnya, dan menggunakan NIO.

Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
System.out.println("Current relative path is: " + s);

Ini menghasilkan Current relative path is: /Users/george/NetBeansProjects/Tutorialsbahwa dalam kasus saya adalah tempat saya menjalankan kelas. Membangun jalur secara relatif, dengan tidak menggunakan pemisah yang mengarah untuk menunjukkan Anda membangun jalur absolut, akan menggunakan jalur relatif ini sebagai titik awal.

geoO
sumber
2
Yang pertama belum diperiksa, tetapi yang kedua benar-benar akan mendapatkan folder rumah Anda. Bukan direktori kerja saat ini di mana aplikasi berjalan.
Peter De Winter
12
Tolong jangan bingung direktori home pengguna ("user.home", / Users / george dalam kasus Anda) dan direktori kerja saat ini ("user.dir", yang akan menjadi direktori dari mana Anda memulai JVM untuk aplikasi Anda , jadi bisa berupa eg / Users / george / workspace / FooBarProject).
David
1
Saya lebih suka cara ini. Ketika saya membutuhkan induk dari direktori yang berfungsi, ini tidak berfungsi Paths.get("").getParent():, ia memberikan null. Sebaliknya ini bekerja: Paths.get("").toAbsolutePath().getParent().
Ole VV
235

Berikut ini berfungsi pada Java 7 dan lebih tinggi (lihat di sini untuk dokumentasi).

import java.nio.file.Paths;

Paths.get(".").toAbsolutePath().normalize().toString();
Dmitry Bespalov
sumber
11
Bagaimana ini lebih baik daripada yang lebih portabel import java.io.File; File(".").getAbsolutePath()?
Evgeni Sergeev
8
Ketika Anda mengatakan portable, maksud Anda ini berfungsi di Java 6 dan sebelumnya? Paths.get()dapat dianggap lebih baik karena memberikan akses langsung ke Pathantarmuka yang lebih kuat .
Ole VV
8
Apa potensi keuntungan menggunakan .normalize()dalam konteks ini?
Ole VV
7
@ OleV.V. Dari Javadoc: ( metode normalisasi )Returns a path that is this path with redundant name elements eliminated.
Stephan
Akan sudah dinormalisasi dalam kasus ini.
JM Becker
73

Ini akan memberi Anda jalur direktori kerja Anda saat ini:

Path path = FileSystems.getDefault().getPath(".");

Dan ini akan memberi Anda path ke file bernama "Foo.txt" di direktori kerja:

Path path = FileSystems.getDefault().getPath("Foo.txt");

Sunting: Untuk mendapatkan jalur absolut dari direktori saat ini:

Path path = FileSystems.getDefault().getPath(".").toAbsolutePath();

* Perbarui * Untuk mendapatkan direktori kerja saat ini:

Path path = FileSystems.getDefault().getPath("").toAbsolutePath();
Menandai
sumber
11
ini hanya mengembalikan '.' untuk saya.
john ktejik
3
Ya, dalam banyak sistem yang akan menjadi referensi ke direktori kerja. Untuk mendapatkan jalur absolut, Anda dapat menambahkan satu lagi pemanggilan metodePath path = FileSystems.getDefault().getPath(".").toAbsolutePath();
Tandai
2
Anda tidak memerlukan foo.txt, cukup masukkan string kosong untuk mendapatkan direktori
john ktejik
1
Pada Windows (10) ini hanya memberi saya Pathobjek menunjuk ke file yang disebut .di dalam direktori kerja saat ini. Menggunakan string kosong, daripada "."bekerja untuk saya.
Kröw
36

Ini solusi untuk saya

File currentDir = new File("");
pengguna2430452
sumber
1
Ini memiliki efek samping ketika Anda menggunakan objek File sebagai induk dari File lain: File baru (File baru (""), "subdir") tidak akan berfungsi seperti yang diharapkan
MRalwasser
13
Untuk memperbaikinya, gunakan new File("").getAbsoluteFile()saja.
MRalwasser
4
Untuk apa nilainya, saya lebih beruntung dengan File (".").
keshlam
Bagaimana Menentukan Jalur Relatif di Jawa Halaman ini membantu saya. Saya juga berasumsi bahwa saya harus menggunakan /ketika membuat jalur relatif. Saya salah, jangan mulai dengan /. ../juga berfungsi untuk naik di pohon direktori.
Irrationalkilla
@keshlam Itu memberi saya file di direktori saat ini disebut ..
Kröw
32

Saya telah menemukan solusi ini di komentar yang lebih baik daripada yang lain dan lebih portabel:

String cwd = new File("").getAbsolutePath();

Atau bahkan

String cwd = Paths.get("").toAbsolutePath();
freedev
sumber
Ini persis sama dengan jawaban dari comeGetSome dan sebenarnya adalah cara Java <7
GoGoris
30

Apa yang membuat Anda berpikir bahwa c: \ windows \ system32 bukan direktori Anda saat ini? The user.dirproperti secara eksplisit untuk menjadi "direktori kerja saat ini Pengguna".

Dengan kata lain, kecuali Anda memulai Java dari baris perintah, c: \ windows \ system32 mungkin adalah CWD Anda. Artinya, jika Anda mengklik dua kali untuk memulai program Anda, CWD tidak akan menjadi direktori tempat Anda mengklik ganda.

Sunting : Tampaknya ini hanya berlaku untuk windows lama dan / atau versi Java.

Paul Wagland
sumber
2
Ini tampaknya tidak benar, setidaknya tidak pada mesin Windows 7 saya menggunakan Java 7. user.dirsecara konsisten folder tempat saya mengklik dua kali file jar.
Jolta
26

Gunakan CodeSource#getLocation().

Ini berfungsi dengan baik dalam file JAR juga. Anda dapat memperoleh CodeSourcepada ProtectionDomain#getCodeSource()dan ProtectionDomainpada gilirannya dapat diperoleh oleh 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());
    }
}
Bigoloo
sumber
2
Ini mengembalikan lokasi file JAR. Bukan apa yang diminta.
Marquis of Lorne
22
this.getClass().getClassLoader().getResource("").getPath()
Peter De Winter
sumber
12
Melempar NPE ketika saya meluncurkan aplikasi saya dari file JAR dengan mengklik dua kali.
Matthew Wise
2
Ini kembali ""jika aplikasi dijalankan dari file JAR, atau elemen CLASSPATH. Bukan apa yang diminta.
Marquis of Lorne
@ Zizouz212 getClass()adalah metode objek, jadi dalam konteks statis hanya menghapus thistidak berfungsi. Anda harus secara eksplisit merujuk kelas yang Anda ikuti MyClass.class.getClassLoader()......
Kröw
Namun demikian itu tidak akan mengembalikan direktori yang berfungsi ...
Angel O'Sphere
18

umumnya, sebagai objek File:

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

Anda mungkin ingin memiliki string yang memenuhi syarat penuh seperti "D: / a / b / c" melakukan:

getCwd().getAbsolutePath()
datangGameSome
sumber
1
Ini berfungsi dengan baik dalam tes Android karena Android tidak termasuk java.nio.file.Files.
iamreptar
Tampaknya tidak berfungsi untuk saya dalam konteks statis (File baru ("") melempar NullPointerException) ..?
nsandersen
2
@nsandersen Anda mungkin menggunakan objek File yang salah: System.out.println (java.io.File baru (""). getAbsolutePath ());
ComeGetSome
13

Saya menggunakan Linux dan mendapatkan hasil yang sama untuk kedua pendekatan ini:

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

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

Paths.get("") docs

System.getProperty("user.dir") docs

Bohdan
sumber
5

Di Linux ketika Anda menjalankan file jar dari terminal , keduanya akan mengembalikan yang sama String: "/ home / CurrentUser" , tidak masalah, di mana file jar Anda. Itu tergantung hanya pada direktori apa yang Anda gunakan dengan terminal Anda, ketika Anda memulai file jar.

Paths.get("").toAbsolutePath().toString();

System.getProperty("user.dir");

Jika Classdengan Anda mainakan dipanggil MainClass, cobalah:

MainClass.class.getProtectionDomain().getCodeSource().getLocation().getFile();

Ini akan mengembalikan Stringdengan path absolut dari jar berkas.

Jan Povolný
sumber
3
Yang bukan apa yang diminta.
Marquis of Lorne
5

Menggunakan Windows user.dir mengembalikan direktori seperti yang diharapkan, tetapi BUKAN ketika Anda memulai aplikasi Anda dengan hak tinggi (dijalankan sebagai admin), dalam hal ini Anda mendapatkan C: \ WINDOWS \ system32

SijeDeHaan
sumber
3

Saya harap Anda ingin mengakses direktori saat ini termasuk paket yaitu Jika program Java Anda ada c:\myApp\com\foo\src\service\MyTest.javadan Anda ingin mencetak hingga c:\myApp\com\foo\src\serviceAnda dapat mencoba kode berikut:

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

Catatan: Kode ini hanya diuji pada Windows dengan Oracle JRE.

JSS
sumber
6
Akan merugikan untuk tidak menurunkan jawaban ini. Tolong pikirkan lebih cermat sebelum memposting. Kode Anda rusak, kecuali semua ini benar: 1. JRE adalah milik Oracle, jika tidak maka tidak akan ada properti sistem "sun.java.command" → NPE; 2. OS adalah Windows ( File.separatorSebagai gantinya, gunakan Filekonstruktor multi-argumen ); 3. classpath dikhususkan pada baris perintah, dan 'direktori saat ini termasuk paket' (??) adalah: a. ditentukan terlebih dahulu, b. ditentukan sepenuhnya, c. cocok dengan CWD persis (bahkan dengan ketidakpekaan huruf besar Windows), dan d. adalah keturunan CWD
Michael Scheper
Itu menunjuk poin 1 dan 2. Tapi kecuali saya kehilangan sesuatu, Anda masih mengandalkan classpath yang ditentukan dalam baris perintah (yaitu tidak dalam variabel lingkungan), dan untuk 'direktori saat ini termasuk paket' (saya mengakui bahwa saya tidak benar - benar mengerti apa yang Anda maksudkan dengan) menjadi keturunan elemen pertama di kelas. Dan masalah pencocokan kasus tetap ada. Maaf jika komentar saya tidak membantu; Saya mengorbankan kejelasan untuk tetap dalam batas karakter komentar.
Michael Scheper
@Inversus, ini hanya "berfungsi sempurna" di beberapa lingkungan; Anda kebetulan cukup beruntung untuk mengujinya. Menulis perangkat lunak yang gagal dalam lingkungan runtime yang sah bukanlah praktik yang baik, bahkan ketika rangkaian lingkungan pengujian Anda tidak cukup luas untuk menyertakannya.
Charles Duffy
@CharlesDuffy Anda benar, itu bukan latihan yang bagus. Untungnya, solusi ini "memecahkan masalah spesifik saya" tidak menyebabkannya "[gagal] di lingkungan runtime yang sah." Bahkan, itu membantu saya mengatasi kegagalan seperti itu dan menulis kode yang lebih kuat, selain memecahkan masalah yang sangat spesifik yang saya miliki (yang hanya terkait dengan pertanyaan / jawaban ini). Saya kira saya hanya beruntung menemukannya.
Inversus
3

Sebutkan bahwa itu hanya dicek Windowstetapi saya pikir ini berfungsi sempurna pada Sistem Operasi lain [ Linux,MacOs,Solaris] :).


Saya memiliki 2 .jar file di direktori yang sama. Saya ingin dari satu .jarfile untuk memulai .jarfile lain yang ada di direktori yang sama.

Masalahnya adalah ketika Anda memulainya dari cmddirektori saat ini system32.


Peringatan!

  • Di bawah ini tampaknya bekerja dengan cukup baik dalam semua tes yang telah saya lakukan bahkan dengan nama folder ;][[;'57f2g34g87-8+9-09!2#@!$%^^&()atau()%&$%^@# berfungsi dengan baik.
  • Saya menggunakan ProcessBuilderdengan di bawah ini sebagai berikut:

🍂 ..

//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;
    }
GOXR3PLUS
sumber
Ini mengembalikan lokasi file JAR. Bukan apa yang diminta.
Marquis of Lorne
@ EJP Lokasi file .jar bukan direktori kerja saat ini dari program java?
GOXR3PLUS
2

Direktori kerja saat ini didefinisikan secara berbeda dalam implementasi Java yang berbeda. Untuk versi tertentu sebelum Java 7 tidak ada cara yang konsisten untuk mendapatkan direktori kerja. Anda dapat mengatasi ini dengan meluncurkan file Java dengan-D dan mendefinisikan variabel untuk menyimpan info

Sesuatu seperti

java -D com.mycompany.workingDir="%0"

Itu tidak benar, tetapi Anda mendapatkan idenya. Lalu System.getProperty("com.mycompany.workingDir")...

MJB
sumber
6
Tidak relevan dengan pertanyaan.
Peter De Winter
1
Itu memang memiliki arti untuk Java - itu adalah lokasi pada disk di mana file yang Anda buka dengan nama path relatif relatif.
Rob I
2
Ya, itu punya arti. Kata-kataku agak salah pilih. Tetapi Anda melewatkan intinya - sebelum Java 7 tidak ada cara untuk mengetahui direktori kerja saat ini, dan implementasi yang berbeda mengaturnya ... berbeda ...
MJB
1

berasumsi bahwa Anda sedang mencoba menjalankan proyek Anda di dalam gerhana, atau netbean atau berdiri sendiri dari baris perintah. Saya telah menulis metode untuk memperbaikinya

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

Untuk digunakan, di mana pun Anda ingin mendapatkan path dasar untuk membaca file, Anda dapat meneruskan kelas anchor Anda ke metode di atas, hasilnya mungkin hal yang Anda butuhkan: D

Terbaik,

bachden
sumber
2
Ini mengembalikan lokasi file JAR. Bukan apa yang diminta.
Marquis of Lorne
@ user207421 ya saya tahu jawaban ini bukan jawaban yang benar untuk pertanyaan itu, tetapi sebagian besar waktu, semua orang ingin mendapatkan "direktori tempat toples berada" bukan "command line working directory".
bachden
0

Tidak ada jawaban yang diposting di sini yang berfungsi untuk saya. Inilah yang berhasil:

java.nio.file.Paths.get(
  getClass().getProtectionDomain().getCodeSource().getLocation().toURI()
);

Edit: Versi terakhir dalam kode saya:

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()
Yang Mulia
sumber
Ini mengembalikan lokasi file JAR. Bukan apa yang diminta.
Marquis of Lorne
0

Ini adalah peluru perak saya ketika saat kebingungan meletus. (Sebut saja sebagai hal utama di utama). Mungkin misalnya JVM diselipkan ke versi yang berbeda oleh IDE. Fungsi statis ini mencari PID proses saat ini dan membuka VisualVM pada pid itu. Kebingungan berhenti di sana karena Anda menginginkan semuanya dan Anda mendapatkannya ...

  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();
    }
}
Kurskinen
sumber
-6

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

Marko Stojkovic
sumber
-7

ini adalah nama direktori saat ini

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

ini adalah jalur direktori saat ini

String path=folder.getPath();
Prasad De Silva
sumber
1
OP menginginkan direktori kerja saat ini dari mana aplikasi itu dijalankan.
Leif Gruenwoldt
Ini adalah direktori home Anda , bukan direktori kerja siapa pun saat ini, kecuali mungkin direktori Anda. Bukan apa yang diminta.
Marquis of Lorne