2013-04-01 34 views
126

dự án của tôi có cấu trúc sau:Làm cách nào để tải tệp từ thư mục tài nguyên?

/src/main/java/ 
/src/main/resources/ 
/src/test/java/ 
/src/test/resources/ 

Tôi có một tập tin trong /src/test/resources/test.csv và tôi muốn tải các tập tin từ một thử nghiệm đơn vị trong /src/test/java/MyTest.java

tôi có mã này mà không làm việc. Nó phàn nàn "Không có tập tin hoặc thư mục".

BufferedReader br = new BufferedReader (new FileReader(test.csv)) 

Tôi cũng đã cố gắng này

InputStream is = (InputStream) MyTest.class.getResourcesAsStream(test.csv)) 

này cũng không hoạt động. Nó trả về null. Tôi đang sử dụng Maven để xây dựng dự án của mình.

+0

Không hoạt động như thế nào?Lỗi của bạn là gì? –

+0

nó trả về giá trị rỗng – codereviewanskquestions

+6

dùng thử this.getClass(). GetResource ("/ test.csv") ' – SRy

Trả lời

123

Hãy thử tiếp theo:

ClassLoader classloader = Thread.currentThread().getContextClassLoader(); 
InputStream is = classloader.getResourceAsStream("test.csv"); 

Nếu ở trên không hoạt động, nhiều dự án đã được thêm vào các lớp sau đây: ClassLoaderUtil (mã here).

Dưới đây là một số ví dụ về cách lớp được sử dụng:

src\main\java\com\company\test\YourCallingClass.java 
src\main\java\com\opensymphony\xwork2\util\ClassLoaderUtil.java 
src\main\resources\test.csv
// java.net.URL 
URL url = ClassLoaderUtil.getResource("test.csv", YourCallingClass.class); 
Path path = Paths.get(url.toURI()); 
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8); 
// java.io.InputStream 
InputStream inputStream = ClassLoaderUtil.getResourceAsStream("test.csv", YourCallingClass.class); 
InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); 
BufferedReader reader = new BufferedReader(streamReader); 
for (String line; (line = reader.readLine()) != null;) { 
    // Process line 
} 
+10

thx cho câu trả lời, bạn có thể vui lòng giải thích lý do tại sao chúng ta nên sử dụng bộ tải rất cụ thể này nhưng không phải của lớp học? –

+1

tuyệt vời, tôi rất ngu ngốc khi tôi đang sử dụng 'Object.class.getClassLoader();', từ một bối cảnh tĩnh không hoạt động - gợi ý này - gần như là, nó bơm '% 20' cho các khoảng trắng cho tôi một 'FileNotFoundException' – ycomp

+3

@ycomp Vì getResource trả về một URL chứ không phải một tệp. Phương thức getFile của java.net.URL ** không ** chuyển đổi URL thành tệp; nó chỉ trả về đường dẫn và các phần truy vấn của URL. Bạn thậm chí không nên chuyển đổi nó thành một Tệp; chỉ cần gọi openStream và đọc từ đó. – VGR

25

Hãy thử:

InputStream is = MyTest.class.getResourceAsStream("/test.csv"); 

IIRC getResourceAsStream() theo mặc định là tương đối so với gói của lớp.

0

Liệu các công việc mã khi không chạy Maven-build jar, ví dụ khi chạy từ IDE của bạn ? Nếu vậy, hãy chắc chắn rằng tập tin thực sự được bao gồm trong bình. Thư mục tài nguyên nên được bao gồm trong tệp pom, trong <build><resources>.

+0

Khi sử dụng nhật thực và mã chạy từ chính IDE. Làm cách nào chúng tôi có thể tải các tài nguyên có tại "/ src/test/resources" trong mã Java cụ thể trong các bài kiểm tra đơn vị. Hãy xem xét một cấu trúc dự án maven tiêu chuẩn. – Bhavesh

2
ClassLoader loader = Thread.currentThread().getContextClassLoader(); 
InputStream is = loader.getResourceAsStream("test.csv"); 

Nếu bạn sử dụng ClassLoader để tìm tài nguyên thì chắc chắn nó sẽ làm giảm hiệu suất của ứng dụng.

+1

Người lập trình phải luôn quan tâm đến hiệu suất. Mặc dù việc tối ưu hóa sớm chắc chắn sẽ tránh được, nhưng việc biết cách tiếp cận hiệu quả hơn là luôn luôn tốt. Nó giống như biết sự khác biệt giữa LinkedList và ArrayList và khi nào sử dụng cái này hay cái kia. – Marvo

+3

@Marvo: Các lập trình viên phải luôn quan tâm đến chất lượng, khả năng và dễ bảo trì, hiệu suất là hàng đợi. –

0

Lớp sau có thể được sử dụng để tải resource từ classpath và cũng nhận được thông báo lỗi phù hợp trong trường hợp có sự cố với filePath nhất định.

import java.io.InputStream; 
import java.nio.file.NoSuchFileException; 

public class ResourceLoader 
{ 
    private String filePath; 

    public ResourceLoader(String filePath) 
    { 
     this.filePath = filePath; 

     if(filePath.startsWith("/")) 
     { 
      throw new IllegalArgumentException("Relative paths may not have a leading slash!"); 
     } 
    } 

    public InputStream getResource() throws NoSuchFileException 
    { 
     ClassLoader classLoader = this.getClass().getClassLoader(); 

     InputStream inputStream = classLoader.getResourceAsStream(filePath); 

     if(inputStream == null) 
     { 
      throw new NoSuchFileException("Resource file not found. Note that the current directory is the source folder!"); 
     } 

     return inputStream; 
    } 
} 
19

Dưới đây là một giải pháp nhanh chóng với việc sử dụng Guava:

import com.google.common.base.Charsets; 
import com.google.common.io.Resources; 

public String readResource(final String fileName, Charset charset) throws IOException { 
     return Resources.toString(Resources.getResource(fileName), charset); 
} 

Cách sử dụng:

String fixture = this.readResource("filename.txt", Charsets.UTF_8) 
-1

tôi nhận được nó để làm việc mà không có tham chiếu đến "lớp học" hoặc "ClassLoader" .

Giả sử chúng tôi có ba trường hợp với vị trí của tệp 'ví dụ.tập tin và thư mục làm việc của bạn (nơi ứng dụng của bạn thực hiện) là home/MyDocuments/chương trình/dự án/myapp:

a) Một thư mục phụ hậu duệ vào thư mục làm việc: myapp/res/files/example.file

b) Một thư mục phụ không hậu duệ vào thư mục làm việc: dự án/files/example.file

b2) Một thư mục phụ không hậu duệ vào thư mục làm việc: chương trình /files/example.file

c) Thư mục gốc: home/mydo cuments/files/example.file (Linux; trong Windows thay thế home/với C :)

1) Lấy con đường đúng đắn: a) String path = "res/files/example.file"; b) String path = "../projects/files/example.file" b2) String path = "../../program/files/example.file" c) String path = "/home/mydocuments/files/example.file"

Về cơ bản, nếu nó là một thư mục gốc, bắt đầu tên đường dẫn có dấu gạch chéo hàng đầu. Nếu đó là thư mục con, không dấu gạch chéo nào phải trước tên đường dẫn. Nếu thư mục con không phải là hậu duệ của thư mục làm việc, bạn phải cd vào nó bằng cách sử dụng "../". Điều này cho hệ thống đi lên một thư mục.

2) Tạo một đối tượng tập tin bằng cách thông qua con đường đúng đắn:

File file = new File(path); 

3) Bạn đang hiện tốt để đi:

BufferedReader br = new BufferedReader(new FileReader(file)); 
0

getResource() đã làm việc tốt với các tập tin nguồn lực đặt chỉ trong src/main/resources. Để nhận tệp ở đường dẫn khác với src/main/resources, hãy nói src/test/java bạn cần tạo tệp đó một cách ngoại lệ.

ví dụ sau đây có thể giúp bạn

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.IOException; 
import java.net.URISyntaxException; 
import java.net.URL; 

public class Main { 
    public static void main(String[] args) throws URISyntaxException, IOException { 
     URL location = Main.class.getProtectionDomain().getCodeSource().getLocation(); 
     BufferedReader br = new BufferedReader(new FileReader(location.getPath().toString().replace("/target/classes/", "/src/test/java/youfilename.txt"))); 
    } 
} 
10

Hãy thử mã chảy vào dự án Spring

ClassPathResource resource = new ClassPathResource("fileName"); 
InputStream inputStream = resource.getInputStream(); 

Hoặc dự án mùa xuân không

ClassLoader classLoader = getClass().getClassLoader(); 
File file = new File(classLoader.getResource("fileName").getFile()); 
InputStream inputStream = new FileInputStream(file); 
+0

Nếu InputStream không được đóng? – 030

3

Bây giờ tôi đang minh họa cho các mã nguồn cho đọc một phông chữ từ thư mục tài nguyên đã tạo maven,

scr/main/nguồn/calibril.ttf

enter image description here

Font getCalibriLightFont(int fontSize){ 
    Font font = null; 
    try{ 
     URL fontURL = OneMethod.class.getResource("/calibril.ttf"); 
     InputStream fontStream = fontURL.openStream(); 
     font = new Font(Font.createFont(Font.TRUETYPE_FONT, fontStream).getFamily(), Font.PLAIN, fontSize); 
     fontStream.close(); 
    }catch(IOException | FontFormatException ief){ 
     font = new Font("Arial", Font.PLAIN, fontSize); 
     ief.printStackTrace(); 
    } 
    return font; 
} 

Nó làm việc cho tôi và tôi hy vọng rằng toàn bộ mã nguồn cũng sẽ giúp bạn, thưởng thức!

0

Chỉ cần sử dụng InputStream InputStream = ClassLoader.getSystemResourceAsStream ("XMLs/employee.xml")

Ở đây có một thư mục XMLs có một file employee.xml.

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