2010-04-19 38 views
11

Tôi đang cố gắng để đọc nội dung tập tin, ví dụ:định vị tập tin trong một classpath

public void myMethod(){ 
    FileInputStream fstream = new FileInputStream(fileLocation); 
    BufferedReader br = new BufferedReader(new InputStreamReader(fstream)); 
    String strLine; 
    while ((strLine = br.readLine()) != null) { 
.... 
.... 
..... 
end while 
end method 

Và tôi có vào lúc bắt đầu của cơ thể lớp private String fileLocation; và ở phần cuối của một lớp Tôi có một phương thức getter và setter cho nó. Bây giờ tôi đang cố gắng tiêm vị trí tệp này từ mùa xuân bên trong bean từ lớp này và tôi chỉ định phương thức init của lớp này. Nhưng tôi nhận được lỗi không thể tìm thấy các tập tin được chỉ định như thể nó không phải trên một classpath nhưng nó là bên trong tập tin chiến tranh? Tôi đang xây dựng dự án với maven và tôi đặt tập tin trong src/main/resources Đây là lỗi tôi nhận được khi cố gắng đọc file:

Error: src\main\resources\ids.txt (The system cannot find the path specified)

Đó là khi tôi đã cố gắng này:

FileInputStream fstream = new FileInputStream("src\\main\\resources\\ids.txt"); 

làm thế nào để tham khảo đúng từ classpath?

EDIT

Khi tôi sửa mã của tôi theo giải pháp @BalusC, đây là cách có vẻ nhưng tôi vẫn nhận được null lỗi:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
    InputStream input = classLoader.getResourceAsStream("src/main/resources/ids.txt"); 
    BufferedReader br = new BufferedReader(new InputStreamReader(input)); 
    String strLine; 
while ((strLine = br.readLine()) != null) { 
    .... 
    .... 
    ..... 
    end while 
    end method 

Trả lời

22

Java IO API dựa trên đĩa địa phương hệ thống tệp, không phải trên đường dẫn lớp. Bên cạnh đó, việc sử dụng các đường dẫn tương đối trong các công cụ Java IO là công thức cho sự cố về tính di động, không dựa vào nó. Để phân bổ tài nguyên trong đường dẫn lớp bạn thường sử dụng ClassLoader#getResource() hoặc ClassLoader#getResourceAsStream().

ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
InputStream input = classLoader.getResourceAsStream("src/main/resources/ids.txt"); 

Điều đó nói rằng, bạn không cần dòng DataInputStream. Bạn thực sự không lấy bất kỳ lợi ích nào từ nó.

Cập nhật: nếu điều đó không hiệu quả, thì tên tài nguyên đơn giản là không hợp lệ hoặc tệp thực sự không có trong đường dẫn lớp mà bạn mong đợi. Xu của tôi trên thư mục src thực sự là gốc của đường dẫn lớp và không phải là một phần của gói. Xóa nó khỏi tên.

Cập nhật 2: để có được tất cả các đĩa gốc đường dẫn hệ thống tập tin mà được bao phủ bởi classpath runtime làm:

for (URL root : Collections.list(Thread.currentThread().getContextClassLoader().getResources(""))) { 
    System.out.println(root); 
} 

Tên tài nguyên cần phải được liên quan đến cả hai người. Rằng nó được đặt trong /WEB-INF/classes trong khi xây dựng là bình thường. Nó được bao phủ bởi classpath. Vấn đề của bạn nằm ở một nơi khác. Bạn có chắc chắn rằng tên tài nguyên là chính xác không? Bạn có chắc chắn rằng bạn đang chạy mã mà bạn cho rằng mình đang chạy không?

+0

@BalusC cảm ơn bạn đã trả lời câu hỏi của tôi Tôi đã cập nhật câu hỏi của mình –

+0

Tôi đã cập nhật câu trả lời của mình để phản ánh điều đó :) – BalusC

+1

@BalusC giống như vậy khi tôi xóa bit 'src', tôi vừa xem bên trong chiến tranh mục tiêu được triển khai trên jboss bên trong tập tin này là vị trí bên trong 'WEB-INF/classes' nhưng trong dự án của tôi trong nhật thực nằm trong' src/main/resources' bất kỳ thủ thuật nào khác lên tay áo của bạn? –

Các vấn đề liên quan