在springboot项目中,resource下创建data目录,然后把test.txt文件放进去,通过下面代码是可以读取其中内容的:
private static List<Integer> test(String filePath) { try { ClassPathResource classpathResource = new ClassPathResource(filePath); File file = classpathResource.getFile(); List<Integer> readLines = Files.readLines(file, Charsets.UTF_8, new LineProcessor<List<Integer>>() { List<Integer> sorts = new ArrayList<>(); @Override public List<Integer> getResult() { return sorts; } @Override public boolean processLine(String s) throws IOException { sorts.add(Integer.parseInt(s)); return true; } }); return readLines; } catch (Exception e) { logger.error("load sort file error...",e); throw new RuntimeException(e); } } public static void main(String... s) { String fp = "data/test.txt"; List<Integer> list = test(fp); }
通过mvn打成jar包:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
用命令行执行,会报如下错误:
Caused by: java.io.FileNotFoundException: class path resource [application.yml] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/D:/sunmnet/JetBrains/workspace/bigdata-parse-table/target/bigdata-parse-table-1.0-SNAPSHOT.jar!/BOOT-INF/classes!/application.yml at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:215) ~[spring-core-4.3.12.RELEASE.jar!/:4.3.12.RELEASE] at org.springframework.core.io.AbstractFileResolvingResource.getFile(AbstractFileResolvingResource.java:53) ~[spring-core-4.3.12.RELEASE.jar!/:4.3.12.RELEASE] at hello.whz.Application.lambda$lookup$0(Application.java:30) [classes!/:1.0-SNAPSHOT] at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:732) [spring-boot-1.5.8.RELEASE.jar!/:1.5.8.RELEASE] ... 14 common frames omitted
这是因为:在jar文件中,不能直接通过文件资源路径拿到文件,但是可以在jar包中拿到文件流。(一定要用流,不要尝试去拿到绝对路径,否则报错!)
原因分析:
Resource resource = new ClassPathResource("data/test/txt"); String path = resource.getFile().getPath());
上述代码的getFile()方法,在本地可以运行成功,但是打包成jar后会报错。主要原因是在jar里,返回的是一个Jar协议地址:jar:file:/xxx/xx.jar!/xxxx
而getFile方法如下:
public static File getFile(URL resourceUrl, String description) throws FileNotFoundException { Assert.notNull(resourceUrl, "Resource URL must not be null"); if (!"file".equals(resourceUrl.getProtocol())) { throw new FileNotFoundException(description + " cannot be resolved to absolute file path because it does not reside in the file system: " + resourceUrl); } else { try { return new File(toURI(resourceUrl).getSchemeSpecificPart()); } catch (URISyntaxException var3) { return new File(resourceUrl.getFile()); } } }
参考:
https://smarterco.de/java-load-file-from-classpath-in-spring-boot/
https://www.renfei.net/posts/1003293