最近要使用c++對windows api相關接口的封裝,有2個接口要求讀寫properties文件。
原覺得網上應該有一大堆資料的,結果拜BAI度的大恩大德,一點相關的資料都沒有。那就只能本身動手豐衣足食。再次感謝十分強大隻是找不到相關資料的BAI度。ios
#pragma oncec++
#ifndef CProperties_H
#define CProperties_Hgit
#include <iostream> #include <fstream> #include <sstream> #include <string> #include <vector> #include <map> #include <windows.h> using namespace std; #define IS_OK 1 #define IS_ERROR 0 typedef bool PSTATUS; class CProperties{ private: string path; protected: public: CProperties(); virtual ~CProperties(); //打開文件 PSTATUS open(const char* path); //實現文件加載到map中 PSTATUS load(); void print(); void close(); vector<string> read(const char *k); PSTATUS write(const char *k,const char* v); void trim_first(string &s); void trim_end(string &s); void trim(string &s); };
#endifgithub
# 源文件windows
#include "stdafx.h" #include "properties.h" /************************************************************************************************/ ///* //*做者:王邵華 //*email:loveofprogram@sina.com //*時間:20180404 //*版本歷程: //*版本號 參與人 事項 //*V1.0.0.1 王邵華 建立 //*************************************************************************************************** //*************************************************************************************************** //*本工具類實現c++對properties文件的讀寫操做, //*1.支持單行註釋如:行首除去空格後以 //、#、<!--內容--> 開始的 //* //這是單行註釋 //* #這是單行註釋 //* <!--這是單行註釋--> //*2.支持節點 但節點並無意義 [section] //*[section0] //*key=value //*[section1] //*key=value //*用到multimap因此存在key鍵有2個值而已,節點並無起到區分的做用,這一點也符合properties配置文件要求規範的 //*3.支持多行註釋 /*第一行,第二行.....*/ //*案例(1)同行有/*..*/ 如:key=123/*oooooo*/b=890 結果保留key=123 //*案例(2)多行有/*..*/ 如:key=123/*ooo //*0000000000000000000 //*ooo*/b=890 結果保留key=123 //*案例(3)行頭行尾有/*..*/如:/*ooooo*/key=123 結果不保留 //* //*/ /************************************************************************************************/ static vector<string> vLine; static multimap<string,string> msKV; static bool mulremark = false;//多行註釋開關 CProperties::CProperties(){}; CProperties::~CProperties(){}; PSTATUS CProperties::open(const char* path){ /**************************************************************/ //判斷是不是文本文檔 而不是文件夾 此代碼存在問題一直hFind = 0xFFFFFFFF //暫留 以便往後優化 //author:王邵華 //time: 20180404 /*WIN32_FIND_DATA fd; bool ret = true; HANDLE hFind = FindFirstFile(LPCWSTR(path), &fd); if ((hFind != INVALID_HANDLE_VALUE) && !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { ret = false; } FindClose(hFind); if (ret) { //文件屬性不對 return IS_ERROR; }*/ /**************************************************************/ if (nullptr == path) { return IS_ERROR; } this->path = path; ifstream ifs; ifs.open(path,ios::in); if (!ifs) { return IS_ERROR;//打開文件失敗 } string sLine; while(!ifs.eof()){ sLine = ""; getline(ifs,sLine); if (mulremark)//已打開多行註釋開關 需判斷該行有沒有關閉開關 { if(sLine.find("*/") != string::npos){ mulremark = false; } continue;//不管開關是否關閉 繼續讀下一行數據 }else { string::size_type pos =sLine.find("/*");string sSubLine; if (pos != string::npos)//改行有多行註釋開關 需打開 { string::size_type epos = sLine.rfind("*/"); mulremark = epos==string::npos || epos<pos?true:false; sSubLine = sLine.substr(0,pos); }else{ sSubLine = sLine; } trim(sSubLine); if (sSubLine.length()<= 0) continue; if (sSubLine[0] == '#')continue; if (sSubLine[0] == '[')continue; if (sSubLine.length()>2 && sSubLine[0] == '/' && sSubLine[1] == '/')continue; if (sSubLine.length()>4 && sSubLine[0] == '<' && sSubLine[1] == '!')continue; vLine.push_back(sSubLine); } } if (ifs.is_open()) { ifs.close(); } return IS_OK; } //實現文件加載到map中 PSTATUS CProperties::load(){ string key,value;string sSubStr; for (int i = 0;i<vLine.size();i++) { string::size_type pos = vLine.at(i).find_first_of("="); if (pos == string::npos) { continue; } key = vLine.at(i).substr(0,pos); value = vLine.at(i).substr(pos+1,vLine.at(i).size()-pos); msKV.insert(make_pair(key,value)); } return IS_OK; } void CProperties::print(){ multimap<string,string>::iterator itr = msKV.begin(); cout<<"################################################################################"<<endl; for (;itr!=msKV.end();itr++) { cout<<"key:"<< itr->first.c_str()<<";value:"<<itr->second.c_str()<<endl; } cout<<"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"<<endl; } vector<string> CProperties::read(const char *k){ vector<string> vVauleCol; if (msKV.size()>0) { multimap<string, string>::size_type cnt = msKV.count(k); multimap<string, string>::iterator iter = msKV.find(k); for(;cnt > 0; cnt--, iter++) { vVauleCol.push_back(iter->second); } } return vVauleCol; } /* *aim:將key=value追加到文本末尾,更新multimap映射插入 */ PSTATUS CProperties::write(const char *k,const char* v){ if (nullptr == k || nullptr == v) { return IS_ERROR; //校驗入參 } ofstream ofs; ofs.open(this->path.c_str(),ios::app); if(!ofs) { return IS_ERROR;//打開文件失敗 } char sStr[1024] = {}; sprintf(sStr,"%s=%s",k,v); ofs<<endl<<sStr; msKV.insert(make_pair(k,v)); if(ofs.is_open()) { ofs.close(); } return IS_OK; } /* *aim:防止屢次造做髒數據干擾 */ void CProperties::close(){ vLine.erase(vLine.begin(),vLine.end()); msKV.erase(msKV.begin(),msKV.end()); } void CProperties::trim_first(string &s){ if( !s.empty() ) s.erase(0,s.find_first_not_of(" ")); } void CProperties::trim_end(string &s){ if( !s.empty() ) s.erase(s.find_last_not_of(" ") + 1); } void CProperties::trim(string &s) { int index = 0; if( !s.empty()) { while( (index = s.find(' ',index)) != string::npos) { s.erase(index,1); } } }
int _tmain1(int argc, _TCHAR* argv[]) {
//########################################################//
//read
//1.建立對象open()文件
//2.load()加載到內存中
//3.read()讀取相關key值的value
//4.close()釋放資源api
CProperties cprop; PSTATUS ret = cprop.open("D:\\job\\greatwall\\test\\bank.properties"); if (ret != IS_OK) { cout<<"打開配置文件失敗"<<endl; getchar(); return 0; } cprop.load(); vector<string> vec = cprop.read("key3"); for (int i=0; i<vec.size();i++) { cout<<vec[i].c_str()<<endl; } cprop.close();
//########################################################//app
//########################################################//
//write
//1.建立對象
//2.load()加載到內存中
//3.write()讀取相關key值的value
//4.close()釋放資源ide
CProperties cprop_write; ret = cprop_write.open("D:\\job\\greatwall\\test\\bank2.properties"); cprop_write.write("aaa","bbb"); cprop_write.write("aaa","bbb"); vec = cprop_write.read("aaa"); for (int i=0; i<vec.size();i++) { cout<<vec[i].c_str()<<endl; } cprop_write.close(); //########################################################// getchar(); return 0; }