Geçerli çalışma dizini Java'da nasıl edinilir?


1029

Mevcut çalışma dizinime java kullanarak erişmek istiyorum.

Kodum:

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

Çıktı:

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

C sürücüsü geçerli dizim olmadığından çıktım doğru değil.

Geçerli dizini nasıl edinebilirim?


2
cdBu komutu yürütürken komut isteminizde komutu yürüttüğünüzde gördüklerinizi buraya yapıştırabilir misiniz?
Nishant

3
Çalışma dizinine erişerek ne yapmaya çalışıyorsunuz? Bunun yerine sınıf yolu kullanılarak yapılabilir mi? Örneğin, dosya sistemindeki bir metin dosyasını okumanız gerekiyorsa, dosyayı sınıf yolundayken kolayca bulabilirsiniz.
earldouglas

1
Nasıl? Lütfen biraz açıklayabilir misiniz?
C grafikleri

1
Sınıf yolundaki bir dosyaya erişme hakkında bilgi için bkz. Stackoverflow.com/questions/1464291/…
downeyt

7
Hata ayıklama amacıyla, çalışma dizini, programın varolan dosyalara erişemediğini bilmek yararlı olabilir.
nsandersen

Yanıtlar:


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

Bu, uygulamanızın başlatıldığı yerden tam bir mutlak yol yazdırır .


Gönderen belgeler :

java.iopaketi, geçerli kullanıcı dizinini kullanarak göreli yol adlarını çözer. Geçerli dizin, sistem özelliği olarak temsil edilir, yani user.dirJVM'nin çağrıldığı dizindir.


25
@ubuntudroid: Bu yüzden özellikle uygulamanın başlatıldığı yerden yazdıracağından bahsetmiştim. Benim tahminim iplik marş commnad istemi (temelde C: \ WINDOWS \ system32 'de) başladıktan sonra doğrudan jar / program çalıştırın. Umarım anlamımı anlarsın. Düştüğünüzü varsayarsak, en azından bir yanıt bıraktığınızı takdir edin. :)
Anuj Patel

1
user.dir, işlemin başlatıldığı klasörün yolunu alır. Uygulamanın ana klasörünün gerçek yolunu bulmak için aşağıdaki cevabıma bakın.
Peter De Winter

1
Yani " geçerli dizini bulmak için ona güvenen tüm kod başarısız." Genel olarak tüm kodlar değil. (Orijinal yorumu düzenlemek için yavaşlamıştım)
SubOptimal

13
@SubOptimal kullanıcı -Duser.dir olarak ayarlanmışsa, bunu özel çalışma dizininde çalıştırmak istiyor olabilir.
barwnikk

5
@indyaah infact bu cevap yanlış, bir kullanıcı çalışma dizini ve bir sistem işleminin geçerli bir çalışma dizini (cwd) arasında küçük bir fark vardır; "user.dir" çoğu zaman bir (java) işleminin cwd'sini gösterir; ancak "user.dir" farklı semantiğe sahiptir ve bir java işleminin cwd'sini elde etmek için kullanılmamalıdır; btw: java işlemi için daha fazla özellik var docs.oracle.com/javase/tutorial/essential/environment/… sadece referans içindir
comeGetSome

381

Bkz. Http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html

Kullanılması java.nio.file.Pathve java.nio.file.PathsJava ne düşündüğünü göstermek için aşağıdakileri yapabilirsiniz, geçerli yoldur. Bu 7 ve üstü için ve NIO kullanır.

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

Bu Current relative path is: /Users/george/NetBeansProjects/Tutorialsbenim durumumda sınıfı koştuğum yer olduğu sonucuna varıyor. Yolları göreli bir şekilde oluşturmak, mutlak bir yol oluşturduğunuzu belirtmek için bir öncü ayırıcı kullanmamak, bu göreceli yolu başlangıç ​​noktası olarak kullanır.


2
Birincisi kontrol etmedi, ikincisi aslında ana klasörünüzü alacak. Uygulamanın çalıştığı geçerli çalışma dizini değil.
Peter De Winter

12
Lütfen kullanıcının ana dizinini ("user.home", / Users / george davanız) ve geçerli çalışma dizinini ("user.dir") karıştırmayın; bu, uygulamanız için JVM'yi başlattığınız dizin olacaktır. , örneğin / Users / george / workspace / FooBarProject) gibi bir şey olabilir.
David

1
Bu yolu tercih ederim. Çalıştığım dizinin üst gerektiğinde, bunu yapar değil iş: Paths.get("").getParent(), o verir null. Bunun yerine bu işleri: Paths.get("").toAbsolutePath().getParent().
Ole VV

235

Java 7 ve sonraki sürümlerde aşağıdakiler çalışır ( belgeler için buraya bakın ).

import java.nio.file.Paths;

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

11
Bu daha taşınabilir olandan nasıl daha iyi import java.io.File; File(".").getAbsolutePath()?
Evgeni Sergeev

8
Taşınabilir dediğinde, Java 6 ve önceki sürümlerde çalıştığını mı söylüyorsun? Paths.get()daha güçlü Patharayüze doğrudan erişim sağladığı için daha iyi düşünülebilir .
Ole VV

8
.normalize()Bu bağlamda kullanmanın potansiyel avantajı nedir ?
Ole VV

7
@ OleV.V. Javadoc'tan: ( yöntemi normalleştir )Returns a path that is this path with redundant name elements eliminated.
Stephan

Bu durumda zaten normalleştirilirdi.
JM Becker

73

Bu size mevcut çalışma dizininizin yolunu verecektir:

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

Bu size çalışma dizininde "Foo.txt" adlı bir dosyanın yolunu verecektir:

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

Düzenleme: Geçerli dizinin mutlak yolunu elde etmek için:

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

* Güncelleme * Geçerli çalışma dizinini almak için:

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

11
bu sadece 'döndürür.' benim için.
john ktejik

3
Evet, birçok dizinde çalışma dizinine başvuru olacaktır. Mutlak yolu elde etmek için bir yöntem daha ekleyebilirsinizPath path = FileSystems.getDefault().getPath(".").toAbsolutePath();
Mark


1
Windows'ta (10) bu sadece geçerli çalışma dizininde Pathadı verilen bir dosyayı işaret eden bir nesne veriyor .. "."Benim için çalışmak yerine boş bir dize kullanmak .
Kröw

36

Bu benim için çözüm

File currentDir = new File("");

1
Böyle bir File nesnesini başka bir Dosyanın üst
öğesi

13
Bunu düzeltmek için new File("").getAbsoluteFile()kullanın.
MRalwasser

4
Değeri için File (".") İle daha iyi şanslar vardı.
keshlam

Java'da Göreli Bir Yol Nasıl Tanımlanır Bu Sayfa bana yardımcı oldu. Ayrıca /göreceli bir yol oluştururken kullanmam gerektiğini varsaydım . Yanılmışım, başlama /. ../ayrıca dizin ağacında yukarı çıkmak için çalışır.
Irrationalkilla

@keshlam Bana şu anki dizinde bir dosya verdi ..
Kröw

32

Bu çözümü diğerlerinden daha iyi ve daha taşınabilir yorumlarda buldum:

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

Ya da

String cwd = Paths.get("").toAbsolutePath();

Bu, comeGetSome'un yanıtıyla tamamen aynıdır ve aslında Java <7 yoludur
GoGoris

30

C: \ windows \ system32'nin şu anki dizininiz olmadığını düşünmenizi sağlayan şey nedir ? user.dirMülkiyet "Kullanıcı Geçerli çalışma dizini" olarak açıkça olduğunu.

Başka bir deyişle, Java'yı komut satırından başlatmazsanız, c: \ windows \ system32 muhtemelen CWD'nizdir. Yani, programınızı başlatmak için çift tıklıyorsanız, CWD'nin çift tıklattığınız dizin olması olası değildir.

Edit : Görünüşe göre bu sadece eski pencereler ve / veya Java sürümleri için geçerlidir.


2
Bu doğru görünmüyor, en azından Java 7 kullanan Windows 7 makinemde değil user.dir, sürekli olarak jar dosyasını çift tıkladığım klasör.
Jolta

26

kullanım CodeSource#getLocation() .

Bu JAR dosyalarında da iyi çalışır. Sen alabilirsiniz CodeSourcetarafından ProtectionDomain#getCodeSource()ve ProtectionDomainsırayla elde edilebilir 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());
    }
}

2
Bu, JAR dosyasının konumunu döndürür. Ne istendi değil.
user207421

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

12
Uygulamamı çift tıklatarak bir JAR dosyasından başlattığımda bir NPE atar.
Matthew Wise

2
""Uygulama bir JAR dosyasından veya bir CLASSPATH öğesinden çalışıyorsa bu geri döner . Ne istendi değil.
user207421

@ Zizouz212 getClass()bir nesne yöntemidir, bu nedenle statik bir bağlamda sadece kaldırma thisişlemi işe yaramaz. Yaptığınız sınıfa açıkça başvurmanız gerekir MyClass.class.getClassLoader()......
Kröw

Yine de çalışma dizinini döndürmez ...
Angel O'Sphere

18

genellikle, bir File nesnesi olarak:

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

"D: / a / b / c" gibi tam nitelikli bir dizeye sahip olmak isteyebilirsiniz:

getCwd().getAbsolutePath()

1
Android java.nio.file.Files içermediği için bu, Android testlerinde iyi çalışır.
iamreptar

Statik bir bağlamda benim için çalışmıyor gibi görünüyor (yeni Dosya ("") NullPointerException atar) ..?
nsandersen

2
@nsandersen muhtemelen yanlış bir File nesnesi kullandınız: System.out.println (new java.io.File (""). getAbsolutePath ());
comeGetSome


5

On Linux Bir çalıştırdığınızda kavanoz dosyayı terminali , bu ikisi de aynı dönecektir String: "/ home / CurrentUser" , youre kavanoz dosya olursa olsun, nerede. Jar dosyasını başlattığınızda, terminalinizle birlikte hangi geçerli dizini kullandığınıza bağlıdır.

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

System.getProperty("user.dir");

Eğer senin Classile mainaranmak MainClasssonra deneyin:

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

Bu , jar dosyasının mutlak yolunuString içeren bir döndürür .


3
Bu ne istendi değil.
user207421

5

Windows user.dir komutunu kullanmak dizini beklendiği gibi döndürür, ancak uygulamanızı yükseltilmiş haklarla başlattığınızda (admin olarak çalıştırdığınızda) DEĞİLDİR, bu durumda C: \ WINDOWS \ system32


3

Umarım paket dahil geçerli dizine erişmek istersiniz yani Java programınız varsa c:\myApp\com\foo\src\service\MyTest.javave o zamana kadar yazdırmak c:\myApp\com\foo\src\serviceistiyorsanız aşağıdaki kodu deneyebilirsiniz:

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

Not: Bu kod yalnızca Oracle JRE içeren Windows'ta test edilmiştir.


6
Bu cevabı küçümsememek kötülük olurdu. Lütfen göndermeden önce daha dikkatli düşünün. Tüm bunlar doğru olmadıkça kodunuz bozulur: 1. JRE Oracle'dır, aksi takdirde "sun.java.command" sistem özelliği olmayacaktır → NPE; 2. İşletim sistemi Windows'dur ( File.separatorBunun yerine kullanın veya çok değişkenli bir Filekurucu); 3. sınıf yolu komut satırında belirtilir ve 'paket içeren geçerli dizin' (??): a. önce belirtilmiş, b. kesinlikle belirtilmiş, c. CWD ile tam olarak eşleşir (Windows'un büyük / küçük harf duyarsızlığında bile) ve d. CWD'nin bir soyundan geliyor
Michael Scheper

Bu nokta 1 ve 2'yi ele alır. Ancak bir şey eksik olmadıkça, komut satırında (yani bir ortam değişkeninde değil) ve 'paket dahil olmak üzere geçerli dizinde' (I) belirtilen sınıfyoluna hala güveniyorsunuz. bununla ne demek istediğini gerçekten anlamadım) özellikle sınıf yolundaki ilk öğenin soyundan gelmek. Ve dava eşleştirme sorunu devam ediyor. Yorumum yardımcı olmadıysa özür dilerim; Yorum karakteri sınırını aşmamak için netliği feda ettim.
Michael Scheper

@Inversus, sadece bazı ortamlarda "mükemmel çalışır"; bunu denemek için yeterince şanslıydın. Meşru çalışma zamanı ortamlarında başarısız olan yazılımlar yazmak, test ortamları kümeniz bunları içerecek kadar geniş olmasa bile iyi bir uygulama değildir.
Charles Duffy

@CharlesDuffy Haklısın, bu iyi bir uygulama değil. Neyse ki, bu çözüm "özel sorunumu çözme" sorusunun "meşru çalışma ortamı ortamında" başarısız olmasına "neden olmadı. Aslında, bu tür bir hatayı çözmeme ve daha sağlam bir kod yazmama yardımcı oldu, ayrıca sahip olduğum çok spesifik sorunu çözmenin yanı sıra (bu soru / cevapla biraz ilgili). Sanırım onu ​​bulduğum için şanslıydım.
Inversus

3

Sadece kontrol edilir Windowsama diğer İşletim Sistemleri [ Linux,MacOs,Solaris] :) mükemmel çalıştığını düşünüyorum .


Aynı dizinde 2 .jar dosyam vardı . Bir .jardosyadan .jaraynı dizindeki diğer dosyayı başlatmak istedim .

Sorun, cmdgeçerli dizinden başlattığınızda olmasıdır system32.


Uyarılar!

  • Aşağıdaki klasör adı ile bile yaptığım tüm test oldukça iyi çalışıyor gibi görünüyor ;][[;'57f2g34g87-8+9-09!2#@!$%^^&()veya ()%&$%^@# iyi çalışıyor.
  • ProcessBuilderAşağıdaki gibi aşağıdaki ile kullanıyorum :

🍂 ..

//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;
    }

Bu, JAR dosyasının konumunu döndürür. Ne istendi değil.
user207421

@EJP .jar dosyasının konumu java programının geçerli çalışma dizini değil mi?
GOXR3PLUS

2

Geçerli çalışma dizini, farklı Java uygulamalarında farklı tanımlanmıştır. Java 7'den önceki belirli sürümler için çalışma dizinini almanın tutarlı bir yolu yoktu. Java dosyasını başlatarak -Dve bilgileri tutmak için bir değişken tanımlayarak bu sorunu çözebilirsiniz.

Gibi bir şey

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

Bu doğru değil, ama fikri anladınız. Sonra System.getProperty("com.mycompany.workingDir")...


6
Soru ile ilgili değil.
Peter De Winter

1
Java için bir anlamı vardır - göreceli yol adları ile açtığınız dosyaların göreceli olduğu diskteki konumdur.
Rob I

2
Evet, bir anlamı var. Sözlerim biraz kötü seçilmişti. Ama noktayı kaçırıyorsunuz - Java 7'den önce mevcut çalışma dizinini bilmenin bir yolu yoktu ve farklı uygulamalar onları farklı bir şekilde ayarladı ...
MJB

1

projenizi eclipse, netbean veya komut satırında tek başına çalıştırmaya çalıştığınızı varsayalım. Bunu düzeltmek için bir yöntem yazdım

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

Dosyayı okumak için temel yol almak istediğiniz her yerde kullanmak için, çapa sınıfınızı yukarıdaki yönteme geçirebilirsiniz, sonuç ihtiyacınız olan şey olabilir: D

En iyi,


2
Bu, JAR dosyasının konumunu döndürür. Ne istendi değil.
user207421

@ user207421 evet Bu cevabın soru için doğru cevap olmadığını biliyorum, ama çoğu zaman, herkes "komut satırı çalışma dizini" yerine "kavanozların bulunduğu dizini" almak istiyor.
Bachden

0

Burada gönderilen cevapların hiçbiri benim için işe yaramadı. İşte işe yarayan:

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

Düzenleme: Kodumun son sürümü:

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

Bu, JAR dosyasının konumunu döndürür. Ne istendi değil.
user207421

0

Bu benim karışık mermi anında gümüş mermim. Belki örneğin JVM, IDE tarafından farklı bir sürüm olarak kaydırılmıştır. Bu statik işlev geçerli işlem PID'sini arar ve bu pid'de VisualVM'yi açar. Karışıklık burada duruyor çünkü hepsini istiyor ve elde ediyorsunuz ...

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


-7

bu geçerli dizin adı

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

bu geçerli dizin yoludur

String path=folder.getPath();

1
OP, uygulamanın çalıştığı yerin geçerli çalışma dizinini istedi.
Leif Gruenwoldt

Bu sizin ana dizininizdir, belki sizinki dışında hiç kimsenin geçerli çalışma dizini değildir. Ne istendi değil.
user207421
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.