JAVA之讀取properties時(shí)路徑的注意問(wèn)題
JAVA讀取properties時(shí)路徑的注意
先來(lái)看看建立的測(cè)試工程目錄
屬性文件我們放在包test下,當(dāng)然了,一般在實(shí)際開(kāi)發(fā)過(guò)程中不建議這樣做,建立把屬性文件放在src目錄下,現(xiàn)在放在包下主要是便于了解路徑的問(wèn)題。
下面來(lái)看一段讀取屬性文件的代碼,屬性文件配置了一個(gè)類(lèi)Hello的K-V鍵值,我們要從中讀取并加載到內(nèi)存中來(lái)。
ReadProperties.properties
v=com.luhy.test.Hello
Hello類(lèi):
package com.luhy.test; public class Hello { public void run(){ System.out.println("Hello"); } }
ReadProperties.java
package com.luhy.test; import java.util.Properties; public class ReadProperties { public static void main(String[] args) throws Exception{ String filename = "com/luhy/test/ReadProperties.properties"; Properties props = new Properties(); props.load(ReadProperties.class.getClassLoader().getResourceAsStream(filename)); String h = props.getProperty("v"); Object o = Class.forName(h).newInstance(); Hello hello = (Hello)o; hello.run(); } }
執(zhí)行完打印輸出:
Hello
下面再來(lái)看一下編譯后的bin目錄
可見(jiàn)編譯后屬性文件被自動(dòng)放到相應(yīng)的包內(nèi),當(dāng)然了,這里的bin相當(dāng)于源碼中的src,實(shí)際開(kāi)發(fā)中一般放在此src目錄下,這樣在發(fā)布項(xiàng)目時(shí)就不用折騰了。
說(shuō)明:
props.load(ReadProperties.class.getClassLoader().getResourceAsStream(filename));
意思是獲得從Properties類(lèi)獲得類(lèi)加載器(類(lèi)加載器主要有四種,分別加載不同類(lèi)型的類(lèi),加載只是把class文件放進(jìn)內(nèi)存,并沒(méi)有產(chǎn)生對(duì)象),并把指定文件轉(zhuǎn)化為流。
這一步,有很多新手,直接往load()里填文件名或具體文件路徑名,程序運(yùn)行時(shí)會(huì)報(bào)錯(cuò)找不到指定路徑。
所以,一定要注意這點(diǎn)。
JAVA讀取properties文件,中文出現(xiàn)亂碼
問(wèn)題的提出
初用properties,讀取java properties文件的時(shí)候如果value是中文,會(huì)出現(xiàn)讀取亂碼的問(wèn)題
問(wèn)題分析
開(kāi)始以為是文件保存編碼問(wèn)題,把eclipse中所有的文件編碼都修改成utf8,問(wèn)題依然存在;
把內(nèi)容復(fù)制到notepad++進(jìn)行utf8編碼轉(zhuǎn)換,問(wèn)題依舊;
上網(wǎng)搜索有人提議重寫(xiě)properties類(lèi)或者用jdk自帶的編碼轉(zhuǎn)換工具,嫌麻煩而且憑感覺(jué)jdk開(kāi)發(fā)者不可能不考慮東亞幾國(guó)的字符編碼問(wèn)題;
因?yàn)閜roperties文件操作的代碼是參考百度文庫(kù)里的一邊文章的,分析其代碼后,發(fā)現(xiàn)其用的是字節(jié)流來(lái)讀取文件,
具體代碼如下:
Properties properties = new Properties(); ? InputStream inputStream = this.getClass().getResourceAsStream("/menu.properties"); ? properties.load(inputStream ); ? System.out.println(properties.getProperty("a")); ?
因?yàn)樽止?jié)流是無(wú)法讀取中文的,所以采取reader把inputStream轉(zhuǎn)換成reader用字符流來(lái)讀取中文。
代碼如下:
Properties properties = new Properties(); ? InputStream inputStream = this.getClass().getResourceAsStream("/menu.properties"); ? BufferedReader bf = new BufferedReader(new ? ?InputStreamReader(inputStream)); ? properties.load(bf); ? System.out.println(properties.getProperty("a")); ?
代碼示例
1、工具類(lèi)
/** ?* 讀取配置文件Properties ?*? ?* @author xl ?* ?*/ public class PropertiesUtil { ?? ?private PropertiesUtil() { ?? ?} ?? ?private static class SingletonHolder { ?? ??? ?private final static PropertiesUtil instance = new PropertiesUtil(); ?? ?} ?? ?public static PropertiesUtil getInstance() { ?? ??? ?return SingletonHolder.instance; ?? ?} ?? ?/** ?? ? * 讀取key字段,配置文件在classes根路徑下xx.properties,在子路徑下xx/xx.properties ?? ? *? ?? ? * @param file ?? ? * @param key ?? ? * @return ?? ? */ ?? ?public String read(String file, String key) { ?? ??? ?InputStream in = getClass().getClassLoader().getResourceAsStream(file); ?? ??? ?BufferedReader bf = new BufferedReader(new InputStreamReader(in));? ?? ??? ?Properties prop = new Properties(); ?? ??? ?String value = ""; ?? ??? ?try { ?? ??? ??? ?prop.load(bf); ?? ??? ??? ?value = prop.getProperty(key); ?? ??? ?} catch (IOException e) { ?? ??? ??? ?e.printStackTrace(); ?? ??? ?} ?? ??? ?return value; ?? ?} }
2、使用工具類(lèi)
/** ?? ? * 獲取properties文件中存放的數(shù)據(jù) ?? ? *? ?? ? * @param req ?? ? * @param resp ?? ? * @return ?? ? * @throws Exception ?? ? */ ?? ?@RequestMapping(value = "/getPropertiesData") ?? ?@ResponseBody ?? ?public Map<String, Object> getPropertiesData(HttpServletRequest req, HttpServletResponse resp) throws Exception { ?? ??? ?Map<String, Object> returnMap = new HashMap<String, Object>(); ?? ??? ?// 獲取請(qǐng)求參數(shù) ?? ??? ?String key = (String) req.getParameter("key"); ?? ??? ?String file = (String) req.getParameter("file"); ?? ??? ?// 從配置文件讀取key對(duì)應(yīng)的value ?? ??? ?String value = PropertiesUtil.getInstance().read(file, key); ?? ??? ?returnMap.put("data", value); ?? ??? ?// 解析返回結(jié)果 ?? ??? ?return returnMap; ?? ?}
完!?。?/p>
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring中使用Hystrix實(shí)現(xiàn)熔斷詳解
這篇文章主要介紹了Java中使用Hystrix實(shí)現(xiàn)熔斷詳解,對(duì)于第一個(gè)問(wèn)題,查看hystrix源碼可以看到,如果有緩存配置是優(yōu)先使用的緩存的,因此如果配置更新,必須要更新緩存,不能使用Hystrix.reset()方法來(lái)更新緩存,需要的朋友可以參考下2023-12-12Java中ArrayList的常見(jiàn)用法示例小結(jié)
本文介紹了Java的ArrayList,它是一個(gè)動(dòng)態(tài)數(shù)組,可以自動(dòng)調(diào)整大小,支持添加、刪除、獲取元素等操作,同時(shí),還討論了如何存儲(chǔ)基本數(shù)據(jù)類(lèi)型以及在多線程環(huán)境下的使用注意事項(xiàng),感興趣的朋友一起看看吧2025-02-02IDEA實(shí)現(xiàn) springmvc的簡(jiǎn)單注冊(cè)登錄功能的示例代碼
這篇文章主要介紹了IDEA實(shí)現(xiàn) springmvc的簡(jiǎn)單注冊(cè)登錄功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06Spring Security認(rèn)證機(jī)制源碼層探究
SpringSecurity是基于Filter實(shí)現(xiàn)認(rèn)證和授權(quán),底層通過(guò)FilterChainProxy代理去調(diào)用各種Filter(Filter鏈),F(xiàn)ilter通過(guò)調(diào)用AuthenticationManager完成認(rèn)證 ,通過(guò)調(diào)用AccessDecisionManager完成授權(quán)2023-03-03