1. 簡介
在本教程中,我們將演示使用 Spring 訪問和加載 classpath 上的文件內容的各種方法。
2. 使用 資源
資源接口有助於抽象對低級資源的訪問。事實上,它以統一的方式支持處理各種類型的文件資源。
讓我們首先看看獲取資源實例的各種方法。
2.1. 手動訪問
要從類路徑訪問資源,我們可以簡單地使用 <em class="resource">ClassPathResource</em>:
public Resource loadEmployeesWithClassPathResource() {
return new ClassPathResource("data/employees.dat");
}默認情況下,<em >ClassPathResource</em> 會選擇線程上下文類加載器和默認系統類加載器之間的其中一個,從而移除一些冗餘信息。
但是,我們也可以直接指定要使用的類加載器:
return new ClassPathResource("data/employees.dat", this.getClass().getClassLoader());或者間接通過指定的類來完成:
return new ClassPathResource(
"data/employees.dat",
Employee.class.getClassLoader());請注意,從Resource,我們可以輕鬆地跳轉到 Java 標準表示形式,例如InputStream或File。
另外需要注意的是,上述方法僅適用於絕對路徑。如果需要指定相對路徑,則可以傳遞第二個class參數。路徑將相對於該類。
new ClassPathResource("../../../data/employees.dat", Example.class).getFile();文件路徑位於上述 Example </em class></em 中。
2.2. 使用 @Value
我們可以通過使用 @Value 注入一個 Resource。
@Value("classpath:data/resource-data.txt")
Resource resourceFile;@Value 也能支持其他前綴,例如 file: 和 url:。
2.3. 使用 ResourceLoader
如果我們要延遲加載我們的資源,可以使用 ResourceLoader:
@Autowired
ResourceLoader resourceLoader;然後我們使用 getResource 方法檢索我們的資源。
public Resource loadEmployeesWithResourceLoader() {
return resourceLoader.getResource(
"classpath:data/employees.dat");
}此外,ResourceLoader 也由所有具體的ApplicationContext 實現,這意味着我們也可以更簡單地依賴於ApplicationContext,如果這種情況更適合我們的情況的話:
ApplicationContext context;
public Resource loadEmployeesWithApplicationContext() {
return context.getResource("classpath:data/employees.dat");
}3. 使用 ResourceUtils 資源工具類
作為一種注意事項,Spring 還可以通過另一種方式獲取資源,但 ResourceUtils Javadoc 明確指出該類主要用於內部使用。
如果我們在代碼中看到對 ResourceUtils 的使用:
public File loadEmployeesWithSpringInternalClass()
throws FileNotFoundException {
return ResourceUtils.getFile(
"classpath:data/employees.dat");
}我們應該仔細考慮理由,因為使用上述的標準方法可能更合適。
4. 讀取資源數據
一旦我們獲取了一個 資源,就很容易讀取其內容。正如我們之前討論的,我們可以輕鬆地從 資源 中獲取一個 文件 或 輸入流 的引用。
假設我們有如下文件 data/employees.dat 在類路徑上:
Joe Employee,Jan Employee,James T. Employee4.1. 通過文件讀取內容
現在我們可以通過調用 getFile 方法讀取其內容。
@Test
public void whenResourceAsFile_thenReadSuccessful()
throws IOException {
File resource = new ClassPathResource(
"data/employees.dat").getFile();
String employees = new String(
Files.readAllBytes(resource.toPath()));
assertEquals(
"Joe Employee,Jan Employee,James T. Employee",
employees);
}儘管如此,需要注意的是,這種方法期望資源存在於文件系統中,而不是在 jar 文件中。
4.2. 以流(InputStream)讀取資源
假設我們的資源位於一個 JAR 包內。
那麼,我們可以將資源讀取為流(InputStream):
@Test
public void whenResourceAsStream_thenReadSuccessful()
throws IOException {
InputStream resource = new ClassPathResource(
"data/employees.dat").getInputStream();
try ( BufferedReader reader = new BufferedReader(
new InputStreamReader(resource)) ) {
String employees = reader.lines()
.collect(Collectors.joining("\n"));
assertEquals("Joe Employee,Jan Employee,James T. Employee", employees);
}
}5. 結論
在本文中,我們探討了使用 Spring 從 classpath 中訪問和讀取資源的幾種方法,包括急時加載和延遲加載,以及從文件系統或 JAR 包中讀取。