Cách lấy đường dẫn tuyệt đối đến tệp trong thư mục / tài nguyên của dự án của bạn


94

Giả sử thiết lập maven tiêu chuẩn.

Giả sử trong thư mục tài nguyên của bạn, bạn có một tệp abc.

Trong Java, làm thế nào tôi có thể lấy đường dẫn tuyệt đối đến tệp?


Bạn có muốn viết một plugin Maven không? Hay bạn muốn truy cập tệp khi chương trình của bạn thực thi?
Gyro cơ không hộp số


Có ba biến thể của giải pháp, tùy thuộc vào tình huống: stackoverflow.com/a/56327069/715269
Gangnus

Câu trả lời:


73

Bạn có thể sử dụng ClassLoader.getResourcephương pháp để có được tài nguyên chính xác.

URL res = getClass().getClassLoader().getResource("abc.txt");
File file = Paths.get(res.toURI()).toFile();
String absolutePath = file.getAbsolutePath();

HOẶC LÀ

Mặc dù điều này có thể không hoạt động mọi lúc, nhưng một giải pháp đơn giản hơn -

Bạn có thể tạo một Fileđối tượng và sử dụng getAbsolutePathphương thức:

File file = new File("resources/abc.txt");
String absolutePath = file.getAbsolutePath();

8
Một lời khuyên sử dụng hạn chế, vì nó dựa vào thư mục làm việc để làm thư mục gốc maven. Và thậm chí sau đó, bạn nên sử dụng target/classes/abc.txtđể tham chiếu tệp, vì đây là nơi chuẩn mà Maven đặt các tệp tài nguyên sau khi xử lý (ví dụ: plugin maven-resources có thể đã thực hiện thay thế thuộc tính trên abc.txt). Tốt hơn nhiều là sử dụng abc.txt qua getResource () từ classpath.
Gyro cơ không hộp số

2
Điều gì sẽ xảy ra nếu một người dùng cuối đang chạy ứng dụng của bạn dưới dạng một JAR thực thi? Sau đó, sẽ không có một Tệp vật lý nào cả. Đây là một lý do khác tại sao bạn nên sử dụng getResource (), và ví dụ: mở luồng đầu vào cho nó tùy thuộc vào những gì bạn muốn làm với nó.
Matthew Wise

6
Điều này có thể được loại bỏ như là câu trả lời chính xác? @Karol S đã trả lời bên dưới - đó phải là câu trả lời chính xác (do đó có sự khác biệt về
lượt ủng hộ

3
Câu trả lời sai. Vui lòng tham khảo bên dưới câu trả lời bằng @Karol
bhathiya-Perera

167

Cách thích hợp thực sự hoạt động:

URL resource = YourClass.class.getResource("abc");
Paths.get(resource.toURI()).toFile();

Bây giờ không quan trọng tệp trong classpath về mặt vật lý, nó sẽ được tìm thấy miễn là tài nguyên thực sự là một tệp chứ không phải mục nhập JAR.

(Dường như hiển nhiên new File(resource.getPath())không hoạt động cho tất cả các đường dẫn! Đường dẫn vẫn được mã hóa URL!)


5
Hoặc có lẽ bạn chỉ có thể làm: new File(resource.toURI()).getAbsolutePath();(tức là tôi không nghĩ rằng bạn cần đối tượng Đường dẫn?)
Dan vua

1
Mẹo hay về toURI (), điều này tránh các khoảng trắng trong đường dẫn của bạn xuất hiện dưới dạng% 20!
Matthew Wise

29
Cảm ơn! Điều này gần như đã làm việc cho tôi. Nhưng tôi phải thực hiện một thay đổi: YourClass.class.getClassLoader (). GetResource ("abc");
yngwietiger

Bạn có thể làm thay thế new File(YourClass.class.getResource("abc").toURI().getPath())nếu bạn muốn.
Mike Rylander

2
Tôi không hiểu điều này đã hoạt động như thế nào đối với rất nhiều người mà không có dấu gạch chéo đầu tiên:.getResource("/abc")
cahen

28

Bạn cần xác định đường dẫn bắt đầu từ /

URL resource = YourClass.class.getResource("/abc");
Paths.get(resource.toURI()).toFile();

12

Tạo cá thể classLoader của lớp bạn cần, sau đó bạn có thể truy cập các tệp hoặc tài nguyên dễ dàng. bây giờ bạn truy cập đường dẫn bằng getPath()phương thức của lớp đó.

 ClassLoader classLoader = getClass().getClassLoader();
 String path  = classLoader.getResource("chromedriver.exe").getPath();
 System.out.println(path);

1

Để trả về một tệp hoặc đường dẫn tệp

URL resource = YourClass.class.getResource("abc");
File file = Paths.get(resource.toURI()).toFile(); // return a file
String filepath = Paths.get(resource.toURI()).toFile().getAbsolutePath();  // return file path

0

Có hai vấn đề trên con đường đi đến con đường tuyệt đối của chúng ta:

  1. Vị trí được tìm thấy sẽ không phải là nơi chứa các tệp nguồn mà là nơi lưu lớp. Và thư mục tài nguyên gần như chắc chắn sẽ nằm ở đâu đó trong thư mục nguồn của dự án.
  2. Các chức năng tương tự để truy xuất tài nguyên hoạt động khác nhau nếu lớp chạy trong một plugin hoặc trong một gói trực tiếp trong không gian làm việc.

Đoạn mã sau sẽ cung cấp cho chúng ta tất cả các đường dẫn hữu ích:

    URL localPackage = this.getClass().getResource("");
    URL urlLoader = YourClassName.class.getProtectionDomain().getCodeSource().getLocation();
    String localDir = localPackage.getPath();
    String loaderDir = urlLoader.getPath();
    System.out.printf("loaderDir = %s\n localDir = %s\n", loaderDir, localDir);

Ở đây nghiên cứu cả hai chức năng có thể được sử dụng để bản địa hóa thư mục tài nguyên. Đối với classnó, nó có thể được nhận theo một trong hai cách, tĩnh hoặc động.


Nếu dự án không có trong plugin, mã nếu chạy trong JUnit, sẽ in:

loaderDir = /C:.../ws/source.dir/target/test-classes/
 localDir = /C:.../ws/source.dir/target/test-classes/package/

Vì vậy, để truy cập src / rest / resources, chúng ta nên đi lên và xuống cây tệp. Cả hai phương pháp đều có thể được sử dụng. Lưu ý, chúng tôi không thể sử dụng getResource(resourceFolderName), vì thư mục đó không nằm trong thư mục đích. Tôi hy vọng không ai đặt tài nguyên vào các thư mục đã tạo.


Nếu lớp nằm trong gói có trong plugin, đầu ra của cùng một bài kiểm tra sẽ là:

loaderDir = /C:.../ws/plugin/bin/
 localDir = /C:.../ws/plugin/bin/package/

Vì vậy, một lần nữa chúng ta nên đi lên và xuống cây thư mục.


Điều thú vị nhất là trường hợp khi gói được khởi chạy trong plugin. Như thử nghiệm plugin JUnit, ví dụ của chúng tôi. Đầu ra là:

loaderDir = /C:.../ws/plugin/
 localDir = /package/

Ở đây chúng ta có thể nhận được đường dẫn tuyệt đối chỉ kết hợp các kết quả của cả hai hàm. Và nó là không đủ. Giữa chúng, chúng ta nên đặt đường dẫn cục bộ của nơi chứa các gói lớp, tương đối với thư mục plugin. Có thể, bạn sẽ phải chèn một cái gì đó như srchoặc src/test/resourceở đây.

Bạn có thể chèn mã vào của bạn và xem các đường dẫn mà bạn có.

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.