在创建Spring Boot Web应用时,有时需要从classpath加载文件。下面是在Jar包/war包中如何读取文件的解决方案:
从war包中读取
方法1:
public static File readByFile(String relativePath) {
File file = null;
try {
file = ResourceUtils.getFile("classpath:" + relativePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return file;
}
方法2:
参考: Java获取路径时Class.getResource()和ClassLoader.getResource()区别。
从jar包中读取
方法1
Resource resource = new ClassPathResource("/" + relativePath);
InputStream fileInputStream = null;
try {
fileInputStream = resource.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
方法2
使用org.springframework.core.io.ResourceLoader
:
@Service("geolocationservice")
public class GeoLocationServiceImpl implements GeoLocationService {
private static final Logger LOGGER = LoggerFactory.getLogger(GeoLocationServiceImpl.class);
private static DatabaseReader reader = null;
private ResourceLoader resourceLoader;
@Inject
public GeoLocationServiceImpl(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@PostConstruct
public void init() {
try {
LOGGER.info("GeoLocationServiceImpl: Trying to load GeoLite2-Country database...");
Resource resource = resourceLoader.getResource("classpath:GeoLite2-Country.mmdb");
InputStream dbAsStream = resource.getInputStream(); // <-- this is the difference
// Initialize the reader
reader = new DatabaseReader
.Builder(dbAsStream)
.fileMode(Reader.FileMode.MEMORY)
.build();
LOGGER.info("GeoLocationServiceImpl: Database was loaded successfully.");
} catch (IOException | NullPointerException e) {
LOGGER.error("Database reader cound not be initialized. ", e);
}
}
@PreDestroy
public void preDestroy() {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
LOGGER.error("Failed to close the reader.");
}
}
}
}
参考: