一、java获取resources下文件路径
项目结构
建议resources下文件名为 英文名称。getPath( )时中文名称会乱码。
1.Thread方式
Thread获取resources下文件路径
String path1 = Thread.currentThread().getContextClassLoader().getResource("mapper").getPath();
String path2 = Thread.currentThread().getContextClassLoader().getResource("mapper/StudentMapper.xml").getPath();
// /D:/Webtest2/Student/student/target/classes/mapper
// /D:/Webtest2/Student/student/target/classes/mapper/StudentMapper.xml
/**
* 通过路径获取的包不能为空(若getResource("static"),则static目录不能为空),否则报null异常。
* 因为在打包时空文件夹被忽略了,这里我们可以通过 target 包进行查看
*/
// System.out.println(Thread.currentThread().getContextClassLoader().getResource("static").getPath());
2. ClassPathResource方式
ClassPathResource方法读取
String path3 = new ClassPathResource("word/title.txt").getPath();
// inputStream:java.io.BufferedInputStream@48eb528b,path:word/title.txt,url:file:/D:/Webtest2/Student/student/target/classes/word/title.txt
/**
* ClassPathResource读取空文件夹会出FileNotFoundException异常
*/
ClassPathResource classPathResource = new ClassPathResource("static");
3.其他方式
/**
* ClassLoader 方式
* idea项目启动可以获取到路径 *打成jar包无法获取路径,会有null异常,
*/
String mapper = ClassLoader.getSystemClassLoader().getResource("mapper").getPath();
String mapper2 = ClassLoader.getSystemClassLoader().getResource("mapper/StudentMapper.xml").getPath();
/*******************************************************************************************/
/**
* 同样idea项目启动可以获取到路径 *打成jar包无法获取路径,会有null异常,
*/
File file = ResourceUtils.getFile("classpath:word/title.txt");
System.out.println("file:"+file.getName()+",path:"+file.getPath()+",url:"+file.toURI());
/*******************************************************************************************/
/**
* 同样idea项目启动可以获取到路径 *jar包也可以获取路径。
*/
this.getClass().getClassLoader().getResource("mapper").getPath();
Resources.class.getClassLoader().getResource("mapper/StudentMapper.xml").getPath();
二、java获取resources下文件信息
idea生成jar包,war包可参考另一篇springboot项目父子多模块打包
1.idea中读取文件
idea项目中可通过getPath( )获取的路径,访问得到File文件。
String mapper = Thread.currentThread().getContextClassLoader().getResource("mapper/StudentMapper.xml").getPath();
File file = new File(mapper);
2.jar包中读取文件
若项目为多模块mvn package构建成一个jar包,仍然可以通过getResource("")方式获取resources下文件路径,但无法通过路径getFile()获得资源文件。当在IDEA里面进行调试的时候,文件是真实存在于磁盘的某个路径的,所以能正常的进行读取,而打成jar后,文件是存在于jar文件里面的资源文件,在磁盘是没有真实的路径的,所以无法通过。
正确的做法是通过流的方式
//推荐的两种方式
// Thread方式 例getResourceAsStream("word/title.txt");
public final static InputStream STREAM1 = Thread.currentThread().getContextClassLoader() .getResourceAsStream("resources下文件路径");
// ClassPathResource方式
public static final ClassPathResource STREAM2 = new ClassPathResource("resources下文件路径");
对resources下txt文件中信息进行去读。使用getResourceAsStream("")获取到文件流,从流中读取每一行的数据。
读取resources下txt文件中的数据
@GetMapping(value = "/2",name = "读取txt文件中信息。idea,jar都可以成功")
public void test2() throws IOException {
List<String> lists = new ArrayList<>();
BufferedReader reader = null;
InputStream inputStream = TestConstant.STREAM2.getInputStream();
try {
String s = null;
/**
* jar包读取文件会有中文乱码
* new BufferedReader(new InputStreamReader(STREAM2,"UTF-8")); 直接转码
*/
reader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
while((s = reader.readLine()) != null){
lists.add(s);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(reader != null){
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
lists.forEach(item -> System.out.println(item));
}
对resources下txt文件进行下载,通过getResourceAsStream(“”)获取到文件流,直接写出数据
读取resources下txt文件进行下载
public final static InputStream STREAM1 = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("word/title.txt");
@GetMapping(value = "/1",name = "以流形式读取resources文件输出(下载)。idea,jar方式都可以成功")
public void test1(HttpServletResponse response) throws Exception{
OutputStream out = response.getOutputStream();
int len = 0;
byte[] bytes = new byte[1024];
while ((len = TestConstant.STREAM1.read(bytes)) != -1){
out.write(bytes,0,len);
}
TestConstant.STREAM1.close();
out.flush();
out.close();
}
3.war包中读取文件
项目打成war包后使用tomcat启动。读取文件路径、文件信息与jar包方式一致。
注意事项:
war包放在ROOT外,请求路径需要加前缀。 main.war,请求路径为 localhost:8888/main/接口
war包启动后,启动文件(META-INF、WEB-INF、org)放入ROOT内请求路径不需要加前缀。