java读取src路径下的txt文件_Java程序使用Maven后无法运行?
問:老師,同樣的代碼,為何我將Java工程改造成Maven后,始終無法運行?
實現(xiàn)的功能:加載abc.txt文件,代碼是寫在了Demo類中。
開發(fā)工具是Idea。
1.以下是普通Java工程的目錄結(jié)構(gòu)。
Demo代碼如下
public class Demo {public static void main(String[] args)throws Exception{InputStream input = new FileInputStream("src/a/abc.txt") ;System.out.println();} }此時,程序能夠正常運行。
2.現(xiàn)在將Java工程,改造成基于Maven的形式。目錄結(jié)構(gòu)如下。
Demo代碼如下。
publicJava工程的classpath是src;Maven工程的classpath有一個是resources。我也做了相應(yīng)修改。但為何,此時用Maven寫的同樣功能代碼,始終報錯如下。
FileNotFoundException:答:
(趕時間的,可以略過分析,直接看本文最后的結(jié)論和源碼)
“路徑問題”首先得思考一個問題:程序中使用的相對路徑,是基于最終執(zhí)行的字節(jié)碼路徑,還是源碼的路徑?(比如原文件是A.java,編譯后的文件是A.class。那么A在加載abc.txt時,“相對路徑”是以“A.java”為參照點,還是以“A.class”為參照點?。
上面這個問題,暫時放一放。先直接看一下造成你疑惑的根本原因:普通的Java工程和Maven等構(gòu)件工具,對.class文件和靜態(tài)資源的打包路徑不同。
1.打開普通Java工程中 字節(jié)碼目錄,如下。
發(fā)現(xiàn)了什么?在普通Java工程中在編譯及運行階段,并不會處理靜態(tài)資源(也就是會忽略abc.txt文件)。因此,要加載abc.txt,就得去它原來的位置,即在src源碼目錄下,如圖所示。
所以,在使用普通Java工程時,就需要在src下面找abc.txt(因為字節(jié)碼目錄中的靜態(tài)資源,會被忽略)。因此,加載路徑是源碼src中的路徑,而不是字節(jié)碼classes中的路徑,如下。
new2.但Maven工程對靜態(tài)資源的處理方式則不同。
我們知道,Maven會將字節(jié)碼和靜態(tài)資源 都打包在 target下,如圖所示。
也就是說,maven會將Demo.class和abc.txt一同打包在 字節(jié)碼(target/classes)目錄下。但要注意:maven默認在讀取路徑時, 是基于字節(jié)碼classes目錄,而不是源碼src目錄,這與普通Java工程完全相反。【因為maven的一個原則:就是想讓 最終的執(zhí)行程序,與源碼相互隔離,互不干擾】。所以,如果使用了maven,靜態(tài)資源的相對路徑獲取方式,就和普通Java工程不一樣了(不能再從src中讀取靜態(tài)資源,而要從classes中讀取)。
講到這里,有同學可能會問“看上圖,可知abc.txt就在Demo.class的上一級。因此在Demo.class中使用../abc.txt不就行了?”??雌饋砗孟窨梢?#xff0c;但實際也不行。
使用../abc.txt的意思是,從當前路徑開始,尋找上一級目錄。這里說的當前路徑好像就是字節(jié)碼路徑中的Demo.class文件本身。但實際情況真的是嗎?使用以下代碼,查看一下當前路徑到底是什么。
public運行結(jié)果:
D:githubJavaCoresrcJavaBook.
發(fā)現(xiàn) ,程序在執(zhí)行時當前路徑是在src下,根本不是classes字節(jié)碼。這又與Maven的原則相違背(Maven默認讀取的路徑是字節(jié)碼classes目錄,而不是源碼src目錄)。【這種特性是jvm底層決定的,我們無法改變】。
以上,有些繞,總結(jié)就是:
java程序在使用相對路徑,加載靜態(tài)資源時:
1.普通Java工程加載的是源文件src目錄中的靜態(tài)資源;
2.Maven工程加載的是字節(jié)碼目錄target/classes中的靜態(tài)資源;
3.在編寫源碼時,程序中相對路徑基于的“當前路徑”是在源文件src目錄下 ,不是在classes目錄下。(也就是當前路徑是基于A.java,而不是基于A.class)。
以上三條中,“1”和“3”是一致的,所以普通Java工程方式加載靜態(tài)資源,沒有什么,直接寫相對路徑就行;但“2”和“3”在讀取路徑時是矛盾的,因此Maven工程在加載靜態(tài)資源時,就不能使用相對路徑,而需要使用絕對路徑。
但還要注意,絕對路徑要以動態(tài)的方式獲取,防止不同環(huán)境之間的差異。
最后,給出Maven方式,獲取靜態(tài)資源的代碼。
public很“簡單”一個問題,是不是還挺繞人的~
- 完 -
推薦閱讀
答疑 | 高并發(fā)都要學哪些技術(shù)?
答疑 | 我是JAVA初級,有必要學架構(gòu)設(shè)計嗎?
Java小白到大神的心路歷程(Java SE)
答疑 | 面試全對,卻沒offer?
答疑 | 背下這300字,面試就能加薪!
總結(jié)
以上是生活随笔為你收集整理的java读取src路径下的txt文件_Java程序使用Maven后无法运行?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何查看dll被那个service占用_
- 下一篇: java log4j logback j