1.ResourceLoader
Spring框架提供了Resource接口和ResourceLoader接口来方便地访问资源文件。为了更好的模拟我们实际生产中的环境,我们直接通过Controller层来对jar中的文件进行访问。
package com.monkeybrother.spring.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
@RestController
public class ResourcesController {
@Autowired
private ResourceLoader resourceLoader;
@GetMapping("readFileFromJarWithResourceLoader")
public void readFileFromJarWithResourceLoader() {
try {
Resource resource = resourceLoader.getResource("classpath:data.txt");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
} catch (IOException e) {
System.err.println("Error reading file from jar: " + e.getMessage());
}
}
}
2.getClass().getResourceAsStream()
可以直接使用getClass().getResourceAsStream()方法,这会返回一个InputStream对象。同样的把这个放在Controller中进行测试:
@GetMapping("readFileFromJarWithResourceAsStream")
public void readFileFromJarWithResourceAsStream() {
InputStream inputStream = getClass().getResourceAsStream("/data.txt");
if (inputStream != null) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
String line;
StringBuilder contentBuilder = new StringBuilder();
while ((line = reader.readLine()) != null) {
contentBuilder.append(line).append("\n");
}
System.out.println(contentBuilder.toString());
} catch (IOException e) {
System.err.println("An error occurred while reading the file: " + e.getMessage());
}
} else {
System.out.println("File not found: application.yml");
}
}
3.org.springframework.util.StreamUtils
Spring框架的StreamUtils类提供了一个便捷的方法来直接读取资源内容到字符串,这样可以简化读取文件的操作:
@GetMapping("readFileFromJarWithStreamUtils")
public void readFileFromJarWithStreamUtils() {
try {
Resource resource = new ClassPathResource("data.txt");
String s = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);
System.out.println(s);
} catch (IOException e) {
throw new RuntimeException("Failed to read file content", e);
}
}
4. 使用 ResourcePatternResolver
**使用Spring框架的ResourcePatternResolver来读取类路径下的资源是一种更灵活的方法,它不仅允许你读取单个资源,还可以匹配和加载多个资源。**下面是一个使用ResourcePatternResolver来读取data.txt文件内容的示例:
@GetMapping("readFileFromJarWithResourcePatternResolver")
public void readFileFromJarWithResourcePatternResolver() {
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
Resource resource = resolver.getResource("data.txt");
if (resource.exists()) {
String content = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);
System.out.println(content);
} else {
System.err.println("The resource 'data.txt' does not exist.");
}
} catch (IOException e) {
e.printStackTrace();
}
}
5.使用Spring Boot的ApplicationContext
Spring Boot的ApplicationContext提供了一种访问资源的方式,它允许你按名称查找资源,这在某些场景下非常有用。在使用的时候我们需要先进行组件的注入:
@Autowired
private ResourceLoader resourceLoader;
@GetMapping("readFileFromJarWithApplicationContext")
public void readFileFromJarWithApplicationContext() {
Resource resource = applicationContext.getResource("classpath:data.txt");
try (InputStream inputStream = resource.getInputStream()) {
String content = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
System.out.println(content);
} catch (IOException e) {
e.printStackTrace();
}
}
**需要注意这里的 是applicationContext.getResource("classpath:data.txt"); 必须为 classpath:data.txt 不能简写 data.txt,**否则会报错,以下是5种方式的完整代码:
package com.monkeybrother.spring.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
@RestController
public class ResourcesController {
@Autowired
private ResourceLoader resourceLoader;
@Autowired
private ApplicationContext applicationContext;
@GetMapping("readFileFromJarWithResourceLoader")
public void readFileFromJarWithResourceLoader() {
try {
Resource resource = resourceLoader.getResource("classpath:data.txt");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
} catch (IOException e) {
System.err.println("Error reading file from jar: " + e.getMessage());
}
}
@GetMapping("readFileFromJarWithResourceAsStream")
public void readFileFromJarWithResourceAsStream() {
InputStream inputStream = getClass().getResourceAsStream("/data.txt");
if (inputStream != null) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
String line;
StringBuilder contentBuilder = new StringBuilder();
while ((line = reader.readLine()) != null) {
contentBuilder.append(line).append("\n");
}
System.out.println(contentBuilder.toString());
} catch (IOException e) {
System.err.println("An error occurred while reading the file: " + e.getMessage());
}
} else {
System.out.println("File not found: application.yml");
}
}
@GetMapping("readFileFromJarWithStreamUtils")
public void readFileFromJarWithStreamUtils() {
try {
Resource resource = new ClassPathResource("data.txt");
String s = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);
System.out.println(s);
} catch (IOException e) {
throw new RuntimeException("Failed to read file content", e);
}
}
@GetMapping("readFileFromJarWithResourcePatternResolver")
public void readFileFromJarWithResourcePatternResolver() {
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
Resource resource = resolver.getResource("data.txt");
if (resource.exists()) {
String content = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);
System.out.println(content);
} else {
System.err.println("The resource 'data.txt' does not exist.");
}
} catch (IOException e) {
e.printStackTrace();
}
}
@GetMapping("readFileFromJarWithApplicationContext")
public void readFileFromJarWithApplicationContext() {
Resource resource = applicationContext.getResource("classpath:data.txt");
try (InputStream inputStream = resource.getInputStream()) {
String content = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
System.out.println(content);
} catch (IOException e) {
e.printStackTrace();
}
}
}