INI檔案格式以及Java編碼實現讀取
阿新 • • 發佈:2019-02-04
/** * 去除ini檔案中的註釋,以";"或"#"開頭,順便去除UTF-8等檔案的BOM頭 * @param source * @return */ private static String removeIniComments(String source){ String result = source; if(result.contains(";")){ result = result.substring(0, result.indexOf(";")); } if(result.contains("#")){ result = result.substring(0, result.indexOf("#")); } return result.trim(); } /** * 讀取 INI 檔案,存放到Map中 * * 支援以‘#’或‘;’開頭的註釋; * 支援行連線符(行末的'\'標記); * 支援預設的global properties; * 支援list格式(非name=value格式處理為list格式); * 支援空行、name/value前後的空格; * 如果有重名,取最後一個; * * 格式(例子)如下 * * # 我是註釋 * ; 我也是註釋 * * name0=value0 # 我是global properties * name10=value10 * * [normal section] # 我是普通的section * name1=value1 # 我是name和value * * [list section] # 我是隻有value的section,以第一個是否包含'='為判斷標準 * value1 * value2 * * @param fileName * @return Map<sectionName, object> object是一個Map(存放name=value對)或List(存放只有value的properties) */ public static Map<String, Object> readIniFile(String fileName){ Map<String, List<String>> listResult = new HashMap<>(); Map<String, Object> result = new HashMap<>(); String globalSection = "global"; //Map中儲存的global properties的key File file = new File(fileName); BufferedReader reader = null; try { //reader = new BufferedReader(new FileReader(file)); //使用BOMInputStream自動去除UTF-8中的BOM!!! reader = new BufferedReader(new InputStreamReader(new BOMInputStream(new FileInputStream(file)))); String str = null; String currentSection = globalSection; //處理預設的section List<String> currentProperties = new ArrayList<>(); boolean lineContinued = false; String tempStr = null; //一次讀入一行(非空),直到讀入null為檔案結束 //先全部放到listResult<String, List>中 while ((str = reader.readLine()) != null) { str = removeIniComments(str).trim(); //去掉尾部的註釋、去掉首尾空格 if("".equals(str)||str==null){ continue; } //如果前一行包括了連線符'\' if(lineContinued == true){ str = tempStr + str; } //處理行連線符'\' if(str.endsWith("\\")){ lineContinued = true; tempStr = str.substring(0,str.length()-1); continue; }else { lineContinued = false; } //是否一個新section開始了 if(str.startsWith("[") && str.endsWith("]")){ String newSection = str.substring(1, str.length()-1).trim(); //如果新section不是現在的section,則把當前section存進listResult中 if(!currentSection.equals(newSection)){ listResult.put(currentSection, currentProperties); currentSection = newSection; //新section是否重複的section //如果是,則使用原來的list來存放properties //如果不是,則new一個List來存放properties currentProperties=listResult.get(currentSection); if(currentProperties==null){ currentProperties = new ArrayList<>(); } } }else{ currentProperties.add(str); } } //把最後一個section存進listResult中 listResult.put(currentSection, currentProperties); reader.close(); } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e1) { } } } //整理拆開name=value對,並存放到MAP中: //從listResult<String, List>中,看各個list中的元素是否包含等號“=”,如果包含,則拆開並放到Map中 //整理後,把結果放進result<String, Object>中 for(String key : listResult.keySet()){ List<String> tempList = listResult.get(key); //空section不放到結果裡面 if(tempList==null||tempList.size()==0){ continue; } if(tempList.get(0).contains("=")){ //name=value對,存放在MAP裡面 Map<String, String> properties = new HashMap<>(); for(String s : tempList){ int delimiterPos = s.indexOf("="); //處理等號前後的空格 properties.put(s.substring(0,delimiterPos).trim(), s.substring(delimiterPos+1, s.length()).trim()); } result.put(key, properties); }else{ //只有value,則獲取原來的list result.put(key, listResult.get(key)); } } return result; } @SuppressWarnings("unchecked") public static void main(String[] args) { //ArrayList<String> readByLines = readByLines("D:/httphosts.txt"); //System.out.println(readByLines); Map<String, Object> ini = readIniFile("D:/test.ini"); for(String k : ini.keySet()){ System.out.println(k + ini.get(k)); } System.out.println(((Map<String, String>)ini.get("myInfo")).get("myName")); }
test.ini檔案內容: