最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java讀取resources中資源文件路徑以及jar中文件無(wú)法讀取的解決

 更新時(shí)間:2023年05月15日 15:38:45   作者:weixin_43229107  
這篇文章主要介紹了Java讀取resources中資源文件路徑以及jar中文件無(wú)法讀取的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Java讀取resources中資源文件路徑以及jar中文件無(wú)法讀取的解決

問(wèn)題描述

現(xiàn)象

作為一個(gè)剛開(kāi)始學(xué)習(xí)java的新人,很多東西都是摸著石頭過(guò)河,踩坑是常有的事。這不,今天我將maven管理的一個(gè)spring boot的WebAPP部署到服務(wù)器上,運(yùn)行直接報(bào)錯(cuò)!納尼?。。”镜嘏艿煤煤玫模坏椒?wù)器就出問(wèn)題,關(guān)鍵是日志文件中的日志不全,無(wú)法馬上定位到問(wèn)題。好吧,一步一步排除問(wèn)題吧!

定位

是不是windows與linux的區(qū)別?不是,我在windows上跑了一下打包后的代碼,也出問(wèn)題了,打包前沒(méi)問(wèn)題,打包后出問(wèn)題了,包有毒!然后我開(kāi)放了日志,一步一步調(diào)試(蛋疼?。?,最終發(fā)現(xiàn)配置文件沒(méi)有加載,路徑出了問(wèn)題。。。

前言

工程文件結(jié)構(gòu)如下所示,目標(biāo)是讀取resources/python/kafka_producer.py文件

1、本地運(yùn)行讀取資源文件

采用getResource進(jìn)行讀?。?/p>

URL urlPath = this.getClass().getResource("/python/kafka_producer.py");
String execStr = String.format("python %s", urlPath.getPath().substring(1));

它是在target文件中讀取,這時(shí)文件是我們熟悉的文件。正常讀取,運(yùn)行。

2、讀取jar包中的文件信息

InputStream is=this.getClass().getResourceAsStream("/python/kafka_producer.py");
BufferedReader br1=new BufferedReader(new InputStreamReader(is));
String s1="";
while((s1=br1.readLine())!=null)
	   System.out.println(s1);

如果你需要運(yùn)行腳本文件,這時(shí)是不能直接通過(guò)路徑獲取的,具體可以看博客點(diǎn)擊。你需要重新將流寫(xiě)入文件中,在運(yùn)行,當(dāng)然,也可以打war包,不用jar包。如果讀取配置文件有一下兩種方式:

InputStream in = this.getClass().getResourceAsStream("/properties/basecom.properties");
Properties properties = new Properties();
properties.load(in);
properties.getProperty("property_name")

或者

    InputStream xmlFile = this.getClass().getResourceAsStream("/jdbcType.xml");
	Document document = xmlReader.read(xmlFile);
	Element xmlRoot = document.getRootElement();
	Element childElement = xmlRoot.element(dbType);
	List<Element> childElements = childElement.elements();
	for (Element child : childElements) {
	}

聊聊Java項(xiàng)目讀取resources資源文件路徑那點(diǎn)事 

在Java程序中讀取resources資源下的文件,由于對(duì)Java結(jié)構(gòu)了解不透徹,遇到很多坑。

正常在Java工程中讀取某路徑下的文件時(shí),可以采用絕對(duì)路徑和相對(duì)路徑,絕對(duì)路徑?jīng)]什么好說(shuō)的,相對(duì)路徑,即相對(duì)于當(dāng)前類的路徑。在本地工程和服務(wù)器中讀取文件的方式有所不同,以下圖配置文件為例:

1、本地讀取資源文件

Java類中需要讀取properties中的配置文件,可以采用文件(File)方式進(jìn)行讀?。?/p>

File file = new File("src/main/resources/properties/test.properties");
InputStream in = new FileInputStream(file);

注意:當(dāng)在IDEA中運(yùn)行(不部署在服務(wù)器上),可以讀取到該文件;

  

原因:JavaWeb項(xiàng)目部署服務(wù)器中,會(huì)將項(xiàng)目打包成Jar包或者war包,此時(shí)就不會(huì)存在 src/main/resources 目錄,JVM會(huì)在編譯項(xiàng)目時(shí),主動(dòng)將 java文件編譯成 class文件 和 resources 下的靜態(tài)文件放在 target/classes目錄下;

理解:Java文件只有編譯成 class文件才會(huì)被JVM執(zhí)行,本地執(zhí)行時(shí)會(huì),當(dāng)前項(xiàng)目即為Java進(jìn)程的工作空間,雖然class文件在target/classes目錄下,但是target/classes不是class文件運(yùn)行的目錄,只是存放的目錄,運(yùn)行目錄還是在IDEA的模塊下,所以運(yùn)行時(shí)會(huì)找到 src/main/resources 資源文件!

2、服務(wù)器(Tomcat)讀取資源文件

當(dāng)工程部署到Tomcat中時(shí),按照上邊方式,則會(huì)拋出異常:FileNotFoundException。

原因:Java工程打包部署到Tomcat中時(shí),properties的路徑變到頂層(classes下),這是由Maven工程結(jié)構(gòu)決定的。

由Maven構(gòu)建的web工程,主代碼放在src/main/java路徑下,資源放在src/main/resources路徑下,當(dāng)構(gòu)建jar包 或 war包時(shí),JVM虛擬機(jī)會(huì)自動(dòng)編譯java文件為class文件存放在 target/classes目錄下,resource資源下的文件會(huì)原封不動(dòng)的拷貝一份到 target/classes 目錄下:

方式一:此時(shí)讀取資源文件時(shí)

采用流(Stream)的方式讀取,并通過(guò)JDK中Properties類加載,可以方便的獲取到配置文件中的信息:

InputStream in = this.getClass().getResourceAsStream("/properties/test.properties");
Properties properties = new Properties();
properties.load(in);
properties.getProperty("name");

重點(diǎn)理解:class.getResourceAStream() 與 class.getClassLoader().getResorceAsStream() 的區(qū)別

1) InputStream inStream = PropertiesTest.class.getResourceAsStream("test.properties");
2) inStream = PropertiesTest.class.getResourceAsStream("/com/test/demo/test.properties")
3) inStream = PropertiesTest.class.getClassLoader().getResourceAsStream("com/test/demo/test.properties");

1)第一種和第二種方式采用 Class 對(duì)象去加載,第三種方式采用 ClassLoader 對(duì)象去加載資源文件,之所以 Class 可以加載資源文件,是因?yàn)?Class 類封裝的 ClassLoader 的 getResourceAsStream() 方法,從 Class 類中的源碼可以看出:

public InputStream getResourceAsStream(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class.
            return ClassLoader.getSystemResourceAsStream(name);
        }
        return cl.getResourceAsStream(name);
 }

理由:??之所以這樣做無(wú)疑還是方便客戶端的調(diào)用,省的每次獲取ClassLoader才能加載資源文件的麻煩!

2).class 是獲取當(dāng)前類的 class 對(duì)象,getClassLoader()是獲取當(dāng)前的類加載器,什么是類加載器?簡(jiǎn)單點(diǎn)說(shuō),就是用來(lái)加載java類的,類加載器就是負(fù)責(zé)把class文件加載進(jìn)內(nèi)存中,并創(chuàng)建一個(gè)java.lang.Class類的一個(gè)實(shí)例,也就是class對(duì)象,并且每個(gè)類的類加載器都不相同,getResourceAsStream(path)是用來(lái)獲取資源的,因?yàn)檫@是ClassLoader(類加載器)獲取資源,而類加載器默認(rèn)是從 classPath 下獲取資源的,因?yàn)檫@下面有class文件。

所以這段代碼總的意思是通過(guò)類加載器在 classPath 目錄下獲取資源,并且是以流的形式。我們知道在Java中所有的類都是通過(guò)加載器加載到虛擬機(jī)中的,而且類加載器之間存在父子關(guān)系,就是子知道父,父不知道子,這樣不同的子加載的類型之間是無(wú)法訪問(wèn)的(雖然它們都被放在方法區(qū)中),所以在這里通過(guò)當(dāng)前類的加載器來(lái)加載資源也就是保證是和類類型是同一個(gè)加載器加載的。

(3)class.getClassLoader().getResourceAsStream() 和 class.getResouceAsStream() 的區(qū)別

a)class.getClassLoader().getResourceAsStream(Stringname)默認(rèn)從classpath中找文件(文件放在resources目錄下),name不能帶"/",否則會(huì)拋空指針。采用相對(duì)路徑, "/"就相當(dāng)于當(dāng)前進(jìn)程的根目錄,即項(xiàng)目根目錄;

inStream = PropertiesTest.class.getClassLoader().getResourceAsStream("com/test/demo/test.properties");

b)class.getResourceAsStream(String name) 是采用絕對(duì)路徑,絕對(duì)路徑是相對(duì)于 classpath 根目錄的路徑,"/" 就代表著 classpath,所以 name 屬性需要前面加上 "/";

inStream = PropertiesTest.class.getResourceAsStream("/com/test/demo/test.properties")

方式二:采用Spring注解

如果工程中使用Spring,可以通過(guò)注解的方式獲取配置信息,但需要將配置文件放到Spring配置文件中掃描后,才能將配置信息放入上下文。

 <context:component-scan base-package="com.xxxx.service"/>
 <context:property-placeholder location="classpath:properties/xxx.properties" ignore-unresolvable="true"/>

然后在程序中可以使用 @Value進(jìn)行獲取properties文件中的屬性值,如下:

 @Value("${xxxt.server}")
 private static String serverUrl;

方式三:采用Spring配置

也可以在Spring配置文件中讀取屬性值,賦予類成員變量

<?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
      <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
          <property name="location" value="classpath:properties/xxx.properties"/>
      </bean>
     <bean id="service" class="com.xxxx.service.ServiceImpl">         <property name="serverUrl" value="${xxxt.server}" />
     </bean>
 </beans>

重點(diǎn):SpringBoot項(xiàng)目啟動(dòng)后,動(dòng)態(tài)的讀取類路徑下文件數(shù)據(jù)

InputStream inputStream = EncryptUtil.class.getResourceAsStream("/HelloServiceEncryptFile.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line = reader.readLine();
// 獲取類路徑下的文件路徑
File path = new File(ResourceUtils.getURL("classpath:").getPath());
if (!path.exists()) {
   path = new File("");
}
log.info("path = {}", path.getAbsolutePath());
File upload = new File(path.getAbsolutePath(), "com/study/service");
if (!upload.exists()) {
    upload.mkdirs();
}
FileOutputStream fos = new FileOutputStream(upload.getAbsolutePath() + File.separator + "hello.txt");
IoUtil.copy(inputStream, fos);
fos.close();
inputStream.close();

注意:此時(shí)我想讀取 jar 包中根路徑下的 HelloServiceEncryptFile.txt 文件,然后重新寫(xiě)入到根路徑下的 com.study/service 路徑下!

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 通過(guò)java記錄數(shù)據(jù)持續(xù)變化時(shí)間代碼解析

    通過(guò)java記錄數(shù)據(jù)持續(xù)變化時(shí)間代碼解析

    這篇文章主要介紹了通過(guò)java記錄數(shù)據(jù)持續(xù)變化時(shí)間代碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • javaweb圖書(shū)商城設(shè)計(jì)之訂單模塊(5)

    javaweb圖書(shū)商城設(shè)計(jì)之訂單模塊(5)

    這篇文章主要為大家詳細(xì)介紹了javaweb圖書(shū)商城設(shè)計(jì)之訂單模塊,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • 詳解java并發(fā)編程(2) --Synchronized與Volatile區(qū)別

    詳解java并發(fā)編程(2) --Synchronized與Volatile區(qū)別

    這篇文章主要介紹了Synchronized與Volatile區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Java中一個(gè)for語(yǔ)句導(dǎo)致無(wú)窮大死循環(huán)的例子

    Java中一個(gè)for語(yǔ)句導(dǎo)致無(wú)窮大死循環(huán)的例子

    這篇文章主要介紹了Java中一個(gè)for語(yǔ)句導(dǎo)致無(wú)窮大死循環(huán)的例子,本文給出的是一個(gè)很特別的例子,這個(gè)例子會(huì)跟你所想的結(jié)果不一樣,需要的朋友可以參考下
    2015-06-06
  • 基于Java實(shí)現(xiàn)Json文件轉(zhuǎn)換為Excel文件

    基于Java實(shí)現(xiàn)Json文件轉(zhuǎn)換為Excel文件

    這篇文章主要為大家詳細(xì)介紹了如何利用Java實(shí)現(xiàn)Json文件轉(zhuǎn)換為Excel文件,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下
    2022-12-12
  • Mybatis?Mapper中多參數(shù)方法不使用@param注解報(bào)錯(cuò)的解決

    Mybatis?Mapper中多參數(shù)方法不使用@param注解報(bào)錯(cuò)的解決

    這篇文章主要介紹了Mybatis?Mapper中多參數(shù)方法不使用@param注解報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
    2022-01-01
  • 解決Spring Boot中Druid連接池“discard long time none received connection“警告

    解決Spring Boot中Druid連接池“discard long time 

    本文主要介紹了解決Spring Boot中Druid連接池“discard long time none received connection“警告,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03
  • MybatisPlus操作符和運(yùn)算值詳解

    MybatisPlus操作符和運(yùn)算值詳解

    在前端到后端的數(shù)據(jù)傳遞中,處理動(dòng)態(tài)運(yùn)算條件是一個(gè)常見(jiàn)的需求,本文介紹了如何在MybatisPlus中處理運(yùn)算符和運(yùn)算值的動(dòng)態(tài)拼接問(wèn)題,感興趣的朋友一起看看吧
    2024-10-10
  • java使用wait和notify實(shí)現(xiàn)線程通信

    java使用wait和notify實(shí)現(xiàn)線程通信

    這篇文章主要為大家詳細(xì)介紹了java如何使用wait和notify實(shí)現(xiàn)線程之間通信,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-10-10
  • Mybatis 級(jí)聯(lián)刪除的實(shí)現(xiàn)

    Mybatis 級(jí)聯(lián)刪除的實(shí)現(xiàn)

    這篇文章主要介紹了Mybatis 級(jí)聯(lián)刪除的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11

最新評(píng)論

淳化县| 息烽县| 招远市| 开江县| 九台市| 丹阳市| 磴口县| 安义县| 郓城县| 南城县| 莆田市| 双鸭山市| 南平市| 安溪县| 辽阳市| 武冈市| 南靖县| 灵寿县| 八宿县| 留坝县| 绥江县| 新安县| 黄骅市| 佛坪县| 甘南县| 嘉义县| 博罗县| 东港市| 纳雍县| 孝义市| 黔江区| 临汾市| 天门市| 额敏县| 城口县| 大同县| 商丘市| 定边县| 绍兴县| 河北省| 张家港市|