Java'da güncel çalışma dizini nasıl alınır?


112

Diyelim ki ana dersim var C:\Users\Justian\Documents\. Programımın içinde olduğunu göstermesini nasıl sağlayabilirim C:\Users\Justian\Documents?

Sabit Kodlama bir seçenek değildir - başka bir yere taşındığında uyarlanabilir olması gerekir.

Bir grup CSV dosyasını bir klasöre dökmek, programın tüm dosyaları tanımasını sağlamak, ardından verileri yüklemek ve işlemek istiyorum. Gerçekten sadece bu klasöre nasıl gidileceğini bilmek istiyorum.


1
bu makaleye bir göz atın .
Matthew J Morrison

1
Ya ana sınıfınız bir jar dosyasındaysa? O zaman ne tür bir sonuç istersiniz?
Mattias Nilsson

1
Neden bunu yapmak zorunda kaldın ki?
Ed S.

1
Sanki ihtiyacınız olan şey, CSV dosyalarının bulunduğu dizin ve .jar dosyasının bu dizine referans verebilmesi gibi, eğer durum buysa cevabımı görün.

Yanıtlar:


149

Bunun bir yolu, sistem özelliğini kullanmaktır, System.getProperty("user.dir");bu size "Özellikler başlatıldığında geçerli çalışma dizini" ni verir. Muhtemelen istediğin bu. javagerçek .jar dosyası makinede başka bir yerde bulunsa bile, sizin durumunuzda işlenecek dosyaların bulunduğu dizinde komutun nerede verildiğini bulmak için. Gerçek .jar dosyasının dizinine sahip olmak çoğu durumda o kadar kullanışlı değildir.

Aşağıdaki komut, .class veya .jar dosyasının .class dosyasının nerede olduğuna bakılmaksızın, komutun çağrıldığı geçerli dizini yazdıracaktır.

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

Eğer içerisindeyseniz /User/me/ve yukarıdaki kodu içeren .jar dosyanız /opt/some/nested/dir/ komutta java -jar /opt/some/nested/dir/test.jar Testise çıktı alacaktır current dir = /User/me.

İyi bir nesne yönelimli komut satırı argüman ayrıştırıcısı kullanmaya da bonus olarak bakmalısınız. Java Simple Argument Parser JSAP'ı şiddetle tavsiye ederim . Bu System.getProperty("user.dir"), davranışı aşmak için kullanmanıza ve alternatif olarak başka bir şey yapmanıza izin verir . Çok daha sürdürülebilir bir çözüm. Bu, dizinde geçişi çok kolay hale getirir ve içeri user.dirhiçbir şey aktarılmazsa geri dönebilir .


Yapabildiğim zaman bunu test edeceğim. Şu .jar sorunuyla gerçekten
meşgulüm

.jar sorununa cevabımdaki bağlantıyı ziyaret ettiniz mi, burada .jar dosyasını ANT ile nasıl oluşturacağımı gösterdim?

Sistem Özelliğinden geçerli çalışma dizini mutlak yolunu döndüren Jarrod kodunun user.dirkullanımı çok kolaydır. System.getProperty ( "user.dir");

74

Kullanın CodeSource#getLocation(). Bu, JAR dosyalarında da iyi çalışıyor. CodeSourceTarafından elde edilebilir ProtectionDomain#getCodeSource()ve ProtectionDomainsırayla ile 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());
    }
}

OP'nin yorumuna göre güncelleme :

Bir grup CSV dosyasını bir klasöre dökmek, programın tüm dosyaları tanımasını sağlamak, ardından verileri yüklemek ve işlemek istiyorum. Gerçekten sadece bu klasöre nasıl gidileceğini bilmek istiyorum.

Bu, programınızdaki göreceli yollarını kodlamayı / bilmeyi gerektirir. Bunun yerine sınıf yoluna yolunu eklemeyi düşünün, böylece kullanabilirsinizClassLoader#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");
    }
});

Veya yolunu main()argüman olarak iletmek için .


3
+1. Bunun işe yaraması için birkaç koşul vardır; en önemlisi "ana sınıfınızın" dosya sisteminden yüklenmesi. Java'da, bu varsayımın yanlış olması çok sıra dışı değildir. Emin dosya sistemi üzerinde bir JAR adresinin sınıfı yüklendiğini tespit Ama eğer, bu işleri yöntemi.
erickson

Her şey bağlıdır, gerçekten. Ben ediyorum çalışırken derleme benim JAR almak için, ama o anda ayrı mesele. Bu konuda yardımcı olabileceğinizi düşünüyorsanız, şu adrese göz atın: stackoverflow.com/questions/3152240/… . Bunu yayınlamanın bir tür ihlal olduğuna eminim, ancak bu konuyla ilgili. Bunu düzeltebilirsem, kesinlikle cevabım bu olacaktır.
Justian Meyer

Neden bunu kodlamam gerekiyor? Daha önce benzer şeyler yaptım. Jar ve klasörümün her zaman benzer bir ilişkiye sahip olacağını varsayın (yani aynı dizinde). Bu doğruysa, kavanozun dizinini alabilir ve ardından klasörü bulmak için değiştirebilirim.
Justian Meyer

JAR dosyasıyla aynı klasördeyse, o zaman zaten sınıf yolundadır. "Sabit kodlama" kelimesi biraz abartılı, aslında "JAR dosyasına göre yollarını bilmek" demek istedim.
BalusC

1
@Moebius: Ha? Java'da yeni misiniz? Javadoc'a bakın . getLocation()Yönteme göre döndürülen tam olarak bunu kullanın . Diğerleri belli ki işe yaramayacak.
BalusC

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

Şunun gibi bir şey yazdırır:

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

Not File.getCanonicalPath()atar bir IOException kontrol ama gibi şeyler kaldıracaktır ../../../


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

bunun sadece "bin" yerine "bin / sınıflar /" yolunu döndüreceğini unutmayın.
android geliştiricisi

Intellij Idea kullanarak çalışan bir uygulamada hata ayıklarken, bu "/C:/Program%20Files/Java/jdk1.8.0_112/:" döndürdü
velocity

5

Ben sadece kullandım:

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

...

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

9
Sizinki işe yaramıyor, bu doğruPaths.get("").toAbsolutePath();
Kra

@ToKra Eğer yapmam Paths.get("my/file").toAbsolutePath()alıyorum /my/filekesinlikle cwd olmadığı.
abergmeier

1
@abergmeier Ben "benim / dosya "dizesi değil"" yazdı
To Kra

5

Mevcut çalışma dizininizi almak istiyorsanız, aşağıdaki satırı kullanın

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

4

Mevcut kaynak kodunun mutlak yolunu istiyorsanız, önerim şudur:

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

Bu, bir IDE üzerinde çalıştırdığınızda veya örneği döndürmek için bir şey kullandığınızda çalışmaz.
Sarp Kaya

Dahili yol java \ lang \ Class Harici yol E: \ BranchProduction1.4.0 \ FilesTestProject \ src Çalışma dizini E: \ BranchProduction1.4.0 \ FilesTestProject \ src \ java \ lang çıktıyı açıklayabilir misiniz?
JAVA

3

Ana sınıfınızın yerel bir sabit diskteki bir dosyada olduğunu kim söylüyor? Sınıflar daha çok JAR dosyalarının içinde toplanır ve bazen ağ üzerinden yüklenir ve hatta anında oluşturulur.

Öyleyse aslında yapmak istediğiniz şey nedir? Muhtemelen bunu yapmanın, sınıfların nereden geldiğine dair varsayımlarda bulunmayan bir yolu vardır.


Bir grup CSV dosyasını bir klasöre dökmek, programın tüm dosyaları tanımasını sağlamak, ardından verileri yüklemek ve işlemek istiyorum. Gerçekten sadece bu klasöre nasıl gidileceğini bilmek istiyorum.
Justian Meyer

Belki bir şeyi kaçırıyorum ama mutlak bir yol işe yarayacak gibi görünüyor. Onu kodlayamayacağınızı söylediniz, ancak başlamak için hangi klasöre bakacağınızı nasıl bileceksiniz?
Chris Thompson

Sorun şu ki, onu sadece kendi bilgisayarıma değil, diğer bilgisayarlara da taşımak istiyorum. Yolu kodlamanın ne kadar işe yarayacağını anlamıyorum. "Jar ve klasörümün her zaman benzer bir ilişkiye sahip olacağını varsayın (yani aynı dizinde). Bu doğruysa, jar dizinini alabilir ve ardından klasörü bulmak için değiştirebilirim." Sabit kodlamamın tek yolu, sabit sürücüden dosyaya giden tam yolu dahil etmek zorunda kalmamamdı. Belki sadece 3 klasör geriye gidebilirim (ör. "Documents \ Project \ Dump \ [dosya / klasör]")
Justian Meyer

Yapmak istediğiniz, jar dosyasının bulunduğu dizine bir tutamaç getirmek olduğunu söyleyebilirim. Bu, gereksinimlerinizi yerine getirir mi?
Chris Thompson
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.