Làm thế nào để lấy thư mục làm việc hiện tại trong Java?


112

Giả sử tôi có lớp học chính của mình C:\Users\Justian\Documents\. Tôi làm cách nào để chương trình của mình hiển thị rằng nó đang ở trong đó C:\Users\Justian\Documents?

Hard-Coding không phải là một tùy chọn - nó cần phải thích ứng nếu được chuyển đến một vị trí khác.

Tôi muốn kết xuất một loạt các tệp CSV trong một thư mục, để chương trình nhận ra tất cả các tệp, sau đó tải dữ liệu và thao tác với chúng. Tôi thực sự chỉ muốn biết cách điều hướng đến thư mục đó.



1
Điều gì sẽ xảy ra nếu lớp chính của bạn nằm trong tệp jar? Bạn muốn kết quả như thế nào sau đó?
Mattias Nilsson

1
Tại sao bạn vẫn cần phải làm điều này?
Ed S.

1
Nghe giống như những gì bạn cần là thư mục chứa tệp CSV và tệp .jar có thể tham chiếu đến thư mục đó, hãy xem câu trả lời của tôi nếu đúng như vậy.

Bản sao có thể xảy ra của Lấy Thư mục Làm việc Hiện tại trong Java
Kevin

Câu trả lời:


149

Một cách sẽ là sử dụng thuộc tính hệ thống, System.getProperty("user.dir"); điều này sẽ cung cấp cho bạn "Thư mục làm việc hiện tại khi các thuộc tính được khởi tạo". Đây có lẽ là những gì bạn muốn. để tìm ra nơi javalệnh được phát hành, trong trường hợp của bạn trong thư mục có tệp để xử lý, mặc dù tệp .jar thực sự có thể nằm ở một nơi khác trên máy. Có thư mục của tệp .jar thực sự không hữu ích trong hầu hết các trường hợp.

Phần sau sẽ in ra thư mục hiện tại từ nơi lệnh được gọi bất kể tệp .class hoặc .jar chứa tệp .class ở đâu.

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

nếu bạn đang ở trong /User/me/và tệp .jar của bạn có chứa mã trên /opt/some/nested/dir/ thì lệnh java -jar /opt/some/nested/dir/test.jar Testsẽ xuất ra current dir = /User/me.

Bạn cũng nên xem xét việc sử dụng một trình phân tích cú pháp đối số dòng lệnh hướng đối tượng tốt. Tôi thực sự khuyên bạn nên dùng JSAP , Trình phân tích cú pháp đối số đơn giản của Java. Điều này sẽ cho phép bạn sử dụng System.getProperty("user.dir")và thay vào đó là một thứ khác để vượt qua hành vi. Một giải pháp dễ bảo trì hơn nhiều. Điều này sẽ làm cho việc chuyển vào thư mục để xử lý rất dễ thực hiện và có thể quay lại user.dirnếu không có gì được chuyển vào.


Tôi sẽ kiểm tra điều này khi tôi có thể. Tôi thực sự bận tâm với điều đó vấn đề .jar: P
Justian Meyer

bạn đã truy cập liên kết trong câu trả lời của tôi cho vấn đề .jar đó, nơi tôi chỉ cách tạo tệp .jar bằng ANT?

Mã từ Jarrod trả về đường dẫn tuyệt đối của thư mục làm việc hiện tại từ Thuộc tính hệ thống user.dirrất dễ sử dụng. System.getProperty ("user.dir");

74

Sử dụng CodeSource#getLocation(). Điều này cũng hoạt động tốt trong các tệp JAR. Bạn có thể lấy CodeSourcebằng ProtectionDomain#getCodeSource()ProtectionDomainlần lượt có thể lấy bằng 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());
    }
}

Cập nhật theo nhận xét của OP:

Tôi muốn kết xuất một loạt các tệp CSV trong một thư mục, để chương trình nhận ra tất cả các tệp, sau đó tải dữ liệu và thao tác với chúng. Tôi thực sự chỉ muốn biết cách điều hướng đến thư mục đó.

Điều đó sẽ yêu cầu mã hóa cứng / biết đường dẫn tương đối của chúng trong chương trình của bạn. Thay vào đó, hãy cân nhắc thêm đường dẫn của nó vào classpath để bạn có thể sử dụngClassLoader#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");
    }
});

Hoặc để chuyển đường dẫn của nó làm main()đối số.


3
+1. Có một số điều kiện để làm cho việc này hoạt động; điều quan trọng nhất là "lớp chính" của bạn được tải từ hệ thống tệp. Trong Java, không có gì lạ khi giả định này là sai. Nhưng, nếu bạn chắc chắn rằng bạn đang tải lớp học của bạn từ một JAR trên hệ thống tập tin, đây là những phương pháp làm việc.
erickson

Tất cả phụ thuộc, thực sự. Tôi đang cố gắng biên dịch JAR của mình, nhưng đó là một vấn đề riêng tại thời điểm này. Nếu bạn cho rằng mình có thể giúp được việc đó, hãy xem: stackoverflow.com/questions/3152240/… . Tôi chắc chắn rằng đăng bài này là một sự vi phạm của một số loại, nhưng nó có liên quan đến vấn đề này. Nếu tôi có thể sửa lỗi đó, đây chắc chắn sẽ là câu trả lời của tôi.
Justian Meyer

Tại sao tôi cần mã hóa nó? Tôi đã làm những điều tương tự trước đây. Giả sử rằng jar và thư mục của tôi sẽ luôn có mối quan hệ tương tự (tức là trong cùng một thư mục). Nếu điều này là đúng, tôi có thể lấy thư mục của jar, sau đó sửa đổi nó để tìm thư mục.
Justian Meyer

Nếu nó nằm trong cùng một thư mục với tệp JAR, thì nó đã ở trong classpath. Từ "hardcoding" hơi phóng đại, ý tôi thực sự là "biết đường dẫn của chúng liên quan đến tệp JAR".
BalusC

1
@Moebius: Hả? Bạn là người mới sử dụng Java? Kiểm tra javadoc . Chỉ cần sử dụng chính xác cái đó như được trả về bằng getLocation()phương thức. Những cái khác rõ ràng sẽ không hoạt động.
BalusC

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

In một cái gì đó như:

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

Lưu ý rằng File.getCanonicalPath()ném IOException đã kiểm tra nhưng nó sẽ xóa những thứ như ../../../


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

lưu ý rằng điều này sẽ trả về đường dẫn đến "bin / class /" chứ không chỉ "bin".
android phát triển

trong khi gỡ một ứng dụng đang chạy bằng IntelliJ IDEA, này trả lại "/C:/Program%20Files/Java/jdk1.8.0_112/:"
vận tốc

5

Tôi vừa sử dụng:

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

...

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

9
Yours nó không làm việc, đây là một là đúngPaths.get("").toAbsolutePath();
Để Kra

@ToKra Nếu tôi Paths.get("my/file").toAbsolutePath()nhận được /my/file, đó chắc chắn không phải là một câu chuyện nhỏ.
abergmeier

1
@abergmeier Tôi đã viết "" trong chuỗi không phải "của tôi / tệp"
Tới Kra,

5

Nếu bạn muốn lấy thư mục làm việc hiện tại của mình thì hãy sử dụng dòng sau

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

4

Nếu bạn muốn đường dẫn tuyệt đối của mã nguồn hiện tại, đề xuất của tôi là:

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

Điều này không hoạt động khi bạn chạy nó trên IDE hoặc sử dụng thứ gì đó để quay phiên bản.
Sarp Kaya

Đường dẫn bên trong là java \ lang \ Class Đường dẫn bên ngoài là E: \ BranchProduction1.4.0 \ FilesTestProject \ src Thư mục làm việc là E: \ BranchProduction1.4.0 \ FilesTestProject \ src \ java \ lang Bạn có thể giải thích kết quả đầu ra không?
JAVA

3

Ai nói rằng lớp chính của bạn nằm trong một tệp trên đĩa cứng cục bộ? Các lớp thường được đóng gói bên trong các tệp JAR và đôi khi được tải qua mạng hoặc thậm chí được tạo ngay lập tức.

Vậy bạn thực sự muốn làm gì? Có lẽ có một cách để làm điều đó mà không phải đưa ra giả định về việc các lớp đến từ đâu.


Tôi muốn kết xuất một loạt các tệp CSV trong một thư mục, để chương trình nhận ra tất cả các tệp, sau đó tải dữ liệu và thao tác với chúng. Tôi thực sự chỉ muốn biết cách điều hướng đến thư mục đó.
Justian Meyer

Có lẽ tôi đang thiếu một cái gì đó nhưng có vẻ như một con đường tuyệt đối sẽ hoạt động. Bạn đã nói rằng bạn không thể mã hóa nó, nhưng làm thế nào bạn biết được thư mục nào cần tìm để bắt đầu?
Chris Thompson

Vấn đề là tôi muốn đưa nó sang các máy tính khác, không chỉ của riêng tôi. Tôi không thấy việc mã hóa đường dẫn sẽ hoạt động như thế nào. "Giả sử rằng jar và thư mục của tôi sẽ luôn có mối quan hệ tương tự (tức là trong cùng một thư mục). Nếu điều này là đúng, tôi có thể lấy thư mục của jar, sau đó sửa đổi nó để tìm thư mục." Cách duy nhất tôi có thể mã hóa nó là nếu tôi không phải bao gồm đường dẫn đầy đủ từ ổ cứng đến tệp. Có lẽ tôi có thể đi chỉ trong 3 thư mục trở lại (tức là "Documents \ Project \ Dump \ [tập tin / thư mục]")
Justian Meyer

Tôi sẽ nói những gì bạn muốn làm là xử lý thư mục chứa tệp jar. Điều đó có đáp ứng được yêu cầu của bạn không?
Chris Thompson
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.