1. 程式人生 > >INI檔案格式以及Java編碼實現讀取

INI檔案格式以及Java編碼實現讀取

	/**
	 * 去除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檔案內容: