项目打包成jar包发布,程序中无法读取静态文件
在war包中可以通过以下方式来获取文件,如下:
public class FilePathTest { public static void main (String[] args) { FileReader reader = null; try { // 方法一:通过文件全路径获取文件 String path = Thread.currentThread().getContextClassLoader().getResource("static/test.txt").getFile(); // String path = ResourceUtils.getURL(ResourceUtils.CLASSPATH_URL_PREFIX +"static/test.txt").getPath(); // String path = ResourceUtils.getURL("classpath:static/test.txt").getPath(); // // 输出结果 /C:/projects/practice/target/classes/static/test.txt System.out.println(path); // File file = new File(path); // 方法二:通过相对路径直接获取文件 // File file = ResourceUtils.getFile("classpath:static/test.txt"); ClassPathResource resource = new ClassPathResource("static/test.txt"); File file = resource.getFile(); reader = new FileReader(file); char[] bytes = new char[21704]; reader.read(bytes); StringBuffer sb = new StringBuffer(); sb.append(bytes); // 输出结果 哈哈,这是一个测试文件 System.out.println(sb.toString()); // String content = new String(bytes); // // 输出结果 哈哈,这是一个测试文件 // System.out.println(content); }catch (Exception e) { e.printStackTrace(); }finally { if (reader != null) { try { reader.close(); }catch (IOException e) { e.printStackTrace(); } } } } }
问题来了,上图的获取方式中有一个共同点:都是根据文件地址来获取文件对象。该文件地址都是编译之后的文件目录,在war包中可以根据该地址获取文件,但是,当打包成JAR包时,无法通过该地址查找到文件对象,那么在JAR包中,如何读取静态文件呢?
在jar包中必须通过流的方式来读取文件
解决方案一:
OutputStream outputStream = null;
InputStream inputStream = null;
ClassPathResource resource = new ClassPathResource("static/test.xls");
File test= new File("D://test.txt");
int len;
byte[] buf = new byte[1024];
try {
outputStream = new FileOutputStream(test);
inputStream = new FileInputStream(resource.getInputStream());
while ((len = inputStream.read(buf))>0) {
outputStream.write(buf,0,len);
}
}catch (IOException io) {
e.printStackTrace();
} finally {
try {
outputStream.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
不获取 java.io.File 对象,而是直接获取输入流: Resource resource = new ClassPathResource("static/test.xls"); BufferedReader br = new BufferedReader(new InputStreamReader(resource.getInputStream())); 说明:构造得到 resource 对象之后直接获取其输入流 resource.getInputStream()。
解决方案二:
使用this.getClass().getClassLoader().getResourceAsStream();这种方式获取文件的流数据
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("static/test.xls");