Làm thế nào để đọc tệp từ đường dẫn tương đối trong dự án Java? java.io.File không thể tìm thấy đường dẫn được chỉ định


113

Tôi có một dự án gồm 2 gói:

  1. tkorg.idrs.core.searchengines
  2. tkorg.idrs.core.searchengines

Trong gói (2) tôi có một tệp văn bản ListStopWords.txt, trong gói (1) tôi có một lớp FileLoadder. Đây là mã trong FileLoader:

File file = new File("properties\\files\\ListStopWords.txt");

Nhưng có lỗi này:

The system cannot find the path specified

Bạn có thể đưa ra một giải pháp để khắc phục nó? Cảm ơn.


12
Cả hai ví dụ gói của bạn đều giống nhau. Bạn không có ý properties.filesđịnh cho 2?
BalusC

Câu trả lời:


173

Nếu nó đã có trong classpath, thì chỉ cần lấy nó từ classpath thay vì từ hệ thống tệp đĩa. Đừng loay hoay với các đường dẫn tương đối vào java.io.File. Chúng phụ thuộc vào thư mục làm việc hiện tại mà bạn hoàn toàn không có quyền kiểm soát từ bên trong mã Java.

Giả sử nó ListStopWords.txtnằm trong cùng một gói với FileLoaderlớp của bạn , thì hãy thực hiện:

URL url = getClass().getResource("ListStopWords.txt");
File file = new File(url.getPath());

Hoặc nếu tất cả những gì bạn đang theo đuổi thực sự là InputStreamcủa nó:

InputStream input = getClass().getResourceAsStream("ListStopWords.txt");

Điều này chắc chắn được ưu tiên hơn việc tạo một new File()urlcó thể không nhất thiết đại diện cho đường dẫn hệ thống tệp đĩa, nhưng nó cũng có thể đại diện cho đường dẫn hệ thống tệp ảo (có thể xảy ra khi JAR được mở rộng vào bộ nhớ thay vì vào một thư mục tạm thời trên hệ thống tệp đĩa) hoặc thậm chí là một đường dẫn mạng mà cả hai đều không thể tiêu hóa theo định nghĩa bởi hàm Filetạo.

Nếu tệp - như tên gói gợi ý- thực sự là một tệp thuộc tính có giá trị đầy đủ (chứa key=valuecác dòng) chỉ với phần mở rộng "sai", thì bạn có thể cung cấp InputStreamngay lập tức cho load()phương thức.

Properties properties = new Properties();
properties.load(getClass().getResourceAsStream("ListStopWords.txt"));

Lưu ý: khi bạn đang cố gắng truy cập nó từ staticngữ cảnh bên trong , hãy sử dụng FileLoader.class(hoặc bất cứ điều gì YourClass.class) thay vì getClass()trong các ví dụ trên.


FileLoader có bị xóa khỏi java không? Tôi đang cố gắng thực hiện việc này từ ngữ cảnh tĩnh (java 6) và tôi không thể tìm thấy bất kỳ cách nào để nhập nó và nó liên tục cho tôi biết rằng nó không thể phân giải thành một loại. Thật kỳ lạ, nó tự động hoàn thành khi tôi nhập, nhưng sau đó lại tiếp tục báo lỗi cho tôi.
turbo

2
ồ, nó phải là ClassLoader.class.
turbo

4
@turbo: FileLoaderlà lớp tùy chỉnh riêng của OP. Nó phải chính xác là lớp mà bạn đang cố lấy tài nguyên. Như vậy, vì vậy NameOfYourCurrentClass.class.getResourceAsStream(...). Các ClassLoader.classsẽ thất bại nếu các ClassLoaderlớp được nạp bởi một classloader khác nhau, trong đó có thể xảy ra trong một "doanh nghiệp" ứng dụng với một hệ thống các classloaders nhiều (giống như một ứng dụng web Java EE).
BalusC

Ồ, tôi hiểu rồi. Tôi không hiểu rằng nó phụ thuộc. Cám ơn giải thích rõ ràng!
turbo

10
Bất kỳ gợi ý nếu tệp không nằm trong cùng một gói? Trong trường hợp của tôi, tôi đang cố mở một tệp nằm trong gói thử nghiệm.
Robin Newhouse

44

Dòng sau có thể được sử dụng nếu chúng ta muốn chỉ định đường dẫn tương đối của tệp.

File file = new File("./properties/files/ListStopWords.txt");  

3
Tôi có thể biết tại sao 3 dấu gạch chéo giữa đường dẫn.
MSNaidu

Lỗi:> Ký tự thoát không hợp lệ trong chuỗi ký tự.
IgorGanapolsky

Làm thế nào để chuyển đổi này thành một InputStream?
IgorGanapolsky

1
@IgorGanapolskyInputStream is = new FileInputStream("./properties/files/ListStopWords.txt");
Cameron Hudson

42

Đường dẫn tương đối hoạt động trong java bằng cách sử dụng. nhà điều hành.

  • . có nghĩa là cùng một thư mục với ngữ cảnh hiện đang chạy.
  • .. nghĩa là thư mục mẹ của ngữ cảnh hiện đang chạy.

Vì vậy, câu hỏi là làm thế nào để bạn biết đường dẫn mà java hiện đang tìm kiếm?

làm một thí nghiệm nhỏ

   File directory = new File("./");
   System.out.println(directory.getAbsolutePath());

Quan sát đầu ra, bạn sẽ biết thư mục hiện tại mà java đang tìm kiếm. Từ đó, chỉ cần sử dụng toán tử ./ để định vị tệp của bạn.

ví dụ nếu đầu ra là

G: \ JAVA8Ws \ MyProject \ content.

và tệp của bạn có trong thư mục MyProject chỉ cần sử dụng

File resourceFile = new File("../myFile.txt");

Hi vọng điêu nay co ich


sau nhiều giờ tìm kiếm câu trả lời này đã cung cấp cho tôi giải pháp
erdostamasa

8
InputStream in = FileLoader.class.getResourceAsStream("<relative path from this class to the file to be read>");
try {
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    String line = null;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
} catch (Exception e) {
    e.printStackTrace();
}

1
@IgorGanapolsky tên của nó là Class. Bạn chỉ có thể tham khảo .classnghĩa đen bằng cách cung cấp tên đầy đủ của lớp của nó.
Tomasz Mularczyk

Tôi nghĩ nó có ý định trở thành FileLoader.
jamesdeath123,


5

Tôi có thể đã nhận xét nhưng tôi có ít đại diện cho điều đó. Câu trả lời của Samrat đã làm công việc cho tôi. Tốt hơn bạn nên xem đường dẫn thư mục hiện tại thông qua đoạn mã sau.

    File directory = new File("./");
    System.out.println(directory.getAbsolutePath());

Tôi chỉ đơn giản sử dụng nó để khắc phục một vấn đề mà tôi đang gặp phải trong dự án của mình. Đảm bảo sử dụng ./ để quay lại thư mục mẹ của thư mục hiện tại.

    ./test/conf/appProperties/keystore 

Tôi đang chạy mã của mình thông qua tomcat và vì vậy thư mục hiện tại không phải là thư mục dự án - Làm cách nào để xác định đường dẫn tương đối đến thư mục gốc của dự án? Tôi hiện đang sử dụng đường dẫn cứng: "C: \\ Users \\ user \\ Desktop \\ Repositories \\ L1_WebShop \\ dblogs.log";
Tiago Redaelli

@TiagoRedaelli xem câu hỏi này: stackoverflow.com/questions/12843217/…
dezible

4

Mặc dù câu trả lời được cung cấp bởi BalusC phù hợp với trường hợp này, nhưng nó sẽ bị hỏng khi đường dẫn tệp chứa khoảng trắng vì trong URL, chúng đang được chuyển đổi thành% 20, đây không phải là tên tệp hợp lệ. Nếu bạn xây dựng đối tượng Tệp bằng URI thay vì Chuỗi, khoảng trắng sẽ được xử lý chính xác:

URL url = getClass().getResource("ListStopWords.txt");
File file = new File(url.toURI());

2

Tôi muốn phân tích cú pháp 'command.json' bên trong src / main // js / Simulator.java. Đối với điều đó, tôi đã sao chép tệp json trong thư mục src và đưa ra đường dẫn tuyệt đối như sau:

Object obj  = parser.parse(new FileReader("./src/command.json"));

2

nhập mô tả hình ảnh ở đây

Giả sử bạn muốn đọc từ resourcesthư mục trong FileSystemlớp.

String file = "dummy.txt";
var path = Paths.get("src/com/company/fs/resources/", file);
System.out.println(path);

System.out.println(Files.readString(path));

Lưu ý:. Không cần dẫn đầu .


1

Đối với tôi thực sự vấn đề là đường dẫn lớp của đối tượng Tệp là từ đâu <project folder path> or ./src, vì vậy sử dụng đã File file = new File("./src/xxx.txt");giải quyết được vấn đề của tôi


0

String basePath = new File ("myFile.txt"). GetAbsolutePath (); đường cơ sở này bạn có thể sử dụng làm đường dẫn chính xác của tệp của mình


-1

Nếu bạn đang cố gắng gọi getClass()từ phương thức Static hoặc khối tĩnh, bạn có thể làm theo cách sau.

Bạn có thể gọi getClass()trên Propertiesđối tượng bạn đang nạp vào.

public static Properties pathProperties = null;

static { 
    pathProperties = new Properties();
    String pathPropertiesFile = "/file.xml;
    InputStream paths = pathProperties.getClass().getResourceAsStream(pathPropertiesFile);
}

Chỉ đơn giản là thiếu một trích dẫn kết thúc.
jamesdeath123,

-1

Nếu tệp văn bản không được đọc, hãy thử sử dụng một đường dẫn tuyệt đối gần hơn (nếu bạn muốn bạn có thể sử dụng đường dẫn tuyệt đối hoàn chỉnh,) như sau:

FileInputStream fin=new FileInputStream("\\Dash\\src\\RS\\Test.txt");

giả sử rằng đường dẫn tuyệt đối là:

C:\\Folder1\\Folder2\\Dash\\src\\RS\\Test.txt
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.