Poco学习(二)
- Poco JSON
- 生成
/////////////////// POCO::JSON ///////////////////// #include "Poco/JSON//Parser.h" #include "Poco/Dynamic/Var.h" #include <fstream> void CreateJson() { Poco::JSON::Object root, temp; Poco::JSON::Array province, cities; // 1. //对中文的支持不好 cities.add("大庆"); cities.add("哈尔滨"); temp.set("name", "黑龙江"); temp.set("cities", cities); province.add(temp); cities.clear(); temp.clear(); cities.add("深圳"); cities.add("广州"); temp.set("name", "广东"); temp.set("cities", cities); province.add(temp); root.set("province", province); root.set("country", "中国"); std::ostringstream osstr; root.stringify(osstr, 2);//中文显示不出 std::string s = osstr.str(); /* 结果: { "country" : "中国", "province" : [ { "cities" : [ "\u00B4\u00F3\u00C7\u00EC", "\u00B9\u0FB6\u0EF1\u00F5" ], "name" : "\u00BA\u00DA\u00C1\uD82B\uDF6D" }, { "cities" : [ "\u00C9\u00EE\u00DB\u00DA", "\u00B9\u00E3\u00D6\u00DD" ], "name" : "\u00B9\u3DAB" } ] } */ //2. cities.add("daqing"); cities.add("haerbin"); temp.set("name", "heilongjiang"); temp.set("cities", cities); province.add(temp); cities.clear(); temp.clear(); cities.add("shenzhen"); cities.add("guangzhou"); temp.set("name", "guangdong"); temp.set("cities", cities); province.add(temp); root.set("province", province); root.set("country", "中国"); Poco::Dynamic::Var js(root); std::string str = js.toString(); /* 结果如下 { "country" : "中国", "province" : [ { "cities" : [ "daqing", "haerbin" ], "name" : "heilongjiang" }, { "cities" : [ "shenzhen", "guangzhou" ], "name" : "guangdong" } ] } */ std::ofstream ofile("test.json"); root.stringify(ofile, 4); ofile.close(); } int main() { CreateJson(); return 0; }
- 解析(sJson必须是UTF8编码的)
try { std::string sJson = "{\"name\":\"LiBai\",\"friends\":[\"DuFu\",\"HEZHIZHANG\"]}"; // "{\"名字\":\"李白\"}"; Poco::JSON::Parser parser; //sJson必须是utf8的,可能只支持 7bit的ASCII码,因为有中文时解析出错:“No legal UTF8 found” Poco::Dynamic::Var ret = parser.parse(sJson); Poco::JSON::Object::Ptr pObj = ret.extract<Poco::JSON::Object::Ptr>(); //1. use Object::Ptr std::string sName = pObj->get("name").toString(); Poco::JSON::Array::Ptr pArr = pObj->getArray("friends"); for (int i = 0; i < pArr->size(); ++i) { std::string s = pArr->get(i).toString(); } for (auto it = pArr->begin(); it != pArr->end(); ++it) { std::string s = it->toString(); } //2. use DynamicStruct Poco::DynamicStruct ds = *pObj; std::string sName2 = ds["name"]; std::string sFriend1 = ds["friends"][0]; std::string sFriend2 = ds["friends"][1]; } catch (Poco::JSON::JSONException& e) { std::string sErr = std::string(e.what()) + "===" + e.message(); }
- 生成和解析
Poco::JSON::Object root, temp; Poco::JSON::Array province, cities; root.setEscapeUnicode(true);//汉字用Unicode表示,例如:"黑龙江"->"\u9ED1\u9F99\u6C5F" std::wstring wsTmp = L"大庆"; cities.add(wsTmp); wsTmp = L"哈尔滨"; cities.add(wsTmp); wsTmp = L"黑龙江"; temp.set("name", wsTmp); temp.set("cities", cities); province.add(temp); root.set("province", province); std::wstring sC(L"中国"); root.set("country", sC); Poco::Dynamic::Var js(root); std::string str = js.toString();//自动转为utf8字符编码 /* 虽然结果如下,但用Poco::JSON可以解析 { "country" : "涓浗", "province" : [ { "cities" : [ "\u5927\u5E86", "\u54C8\u5C14\u6EE8" ], "name" : "\u9ED1\u9F99\u6C5F" } ] } */ try { std::string sJson = str;//"{\"name\":\"LiBai\",\"friends\":[\"DuFu\",\"HEZHIZHANG\"]}"; // "{\"名字\":\"李白\"}"; Poco::JSON::Parser parser; //sJson必须是utf8的,可能只支持 7bit的ASCII码,因为有中文时解析出错:“No legal UTF8 found” Poco::Dynamic::Var ret = parser.parse(sJson); Poco::JSON::Object::Ptr pObj = ret.extract<Poco::JSON::Object::Ptr>(); //2. use DynamicStruct Poco::DynamicStruct ds = *pObj; std::string stemp; std::string sName2 = ds["country"]; UTF8_to_ANSI(sName2, stemp);//中国 std::string sProvince = ds["province"][0]["name"]; UTF8_to_ANSI(sProvince, stemp);//黑龙江 std::string sCity1 = ds["province"][0]["cities"][0]; UTF8_to_ANSI(sCity1, stemp);//大庆 std::string sCity2 = ds["province"][0]["cities"][1]; UTF8_to_ANSI(sCity2, stemp);//哈尔滨 } catch (Poco::JSON::JSONException& e) { std::string sErr = std::string(e.what()) + "===" + e.message(); }
注:UTF8_to_ANSI 函数,参见 my functions.h 的第3个。
- Poco Base64 编码解码
基于字符串
#include <sstream> #include <Poco/Base64Encoder.h> #include <Poco/Base64Decoder.h> #include <Poco/StreamCopier.h> int main(int argc, char** argv) { //base64编码 std::string s1("12345"); std::stringstream ss; std::ostringstream oss; ss << s1; Poco::Base64Encoder encoder(oss); Poco::StreamCopier::copyStream(ss, encoder); encoder.close();//这句很重要 std::string s2 = oss.str();//"MTIzNDU=" /////////////////////////////// // 注意:若无 encoder.close(); // 则, "123456" -> "MTIzNDU2" ok // "12345" -> "MTIz" error. because of "MTIz" ->(123) /////////////////////////////// return 0; } //解码 std::stringstream ss; std::ostringstream oss; ss << "MTIzNDU2"; Poco::Base64Decoder decoder(ss); Poco::StreamCopier::copyStream(decoder, oss); std::string s = oss.str();//"123456" //或者用下面的代替上两行 //std::string s2; //Poco::StreamCopier::copyToString(decoder, s2); //参考:https://blog.csdn.net/lizhi200404520/article/details/8860282 // 网上的例子 { std::string s("\00\01\02\03", 4); std::ostringstream str; Poco::Base64Encoder encoder(str); encoder << s; encoder.close(); std::string sRet = str.str();//"AAECAw==" } { std::istringstream istr("MTIzNDU="); Poco::Base64Decoder decoder(istr); std::string s; decoder >> s;//"12345" }
Poco给的例子(基于文件流)
/////////////// 编码 /////////////////////// #include "Poco/Base64Encoder.h" #include "Poco/StreamCopier.h" #include <iostream> #include <fstream> using Poco::Base64Encoder; using Poco::StreamCopier; int main(int argc, char** argv) { if (argc != 3) { std::cout << "usage: " << argv[0] << ": <input_file> <output_file>" << std::endl << " read <input_file>, base64-encode it and write the result to <output_file>" << std::endl; return 1; } std::ifstream istr(argv[1], std::ios::binary); if (!istr) { std::cerr << "cannot open input file: " << argv[1] << std::endl; return 2; } std::ofstream ostr(argv[2]); if (!ostr) { std::cerr << "cannot open output file: " << argv[2] << std::endl; return 3; } Base64Encoder encoder(ostr); StreamCopier::copyStream(istr, encoder); if (!ostr) { std::cerr << "error writing output file: " << argv[2] << std::endl; return 4; } return 0; } ////////////// 解码 //////////////////////// #include "Poco/Base64Decoder.h" #include "Poco/StreamCopier.h" #include <iostream> #include <fstream> using Poco::Base64Decoder; using Poco::StreamCopier; int main(int argc, char** argv) { if (argc != 3) { std::cout << "usage: " << argv[0] << ": <input_file> <output_file>" << std::endl << " read base64-encoded <input_file>, decode it and write the result to <output_file>" << std::endl; return 1; } std::ifstream istr(argv[1]); if (!istr) { std::cerr << "cannot open input file: " << argv[1] << std::endl; return 2; } std::ofstream ostr(argv[2], std::ios::binary); if (!ostr) { std::cerr << "cannot open output file: " << argv[2] << std::endl; return 3; } Base64Decoder decoder(istr); StreamCopier::copyStream(decoder, ostr); if (!ostr) { std::cerr << "error writing output file: " << argv[2] << std::endl; return 4; } return 0; }
- Poco MD5 加密
#include "Poco/MD5Engine.h" #include "Poco/DigestStream.h" #include "Poco/StreamCopier.h" #include <fstream> #include <iostream> using Poco::DigestEngine; using Poco::MD5Engine; using Poco::DigestOutputStream; using Poco::StreamCopier; int main(int argc, char** argv) { if (argc != 2) { std::cout << "usage: " << argv[0] << ": <input_file>" << std::endl << " create the MD5 digest for <input_file>" << std::endl; return 1; } std::ifstream istr(argv[1], std::ios::binary); if (!istr) { std::cerr << "cannot open input file: " << argv[1] << std::endl; return 2; } MD5Engine md5; DigestOutputStream dos(md5); StreamCopier::copyStream(istr, dos); dos.close(); std::string sMD5 = DigestEngine::digestToHex(md5.digest()); std::cout << DigestEngine::digestToHex(md5.digest()) << std::endl; return 0; }
- Poco 压缩文件 解压文件 deflate inflate
压缩文件:
#include "Poco/DeflatingStream.h" #include "Poco/StreamCopier.h" #include <fstream> using Poco::DeflatingOutputStream; using Poco::StreamCopier; int main() { char* filename = "F:/test.xls"; std::ifstream ifile(filename, std::ios::binary); if (!ifile.is_open()) return -1; filename = "F:/test.zlib"; std::ofstream ofile(filename, std::ios::binary); if (!ofile.is_open()) return -1; // DeflatingOutputStream(std::ostream& ostr, DeflatingStreamBuf::StreamType type = DeflatingStreamBuf::STREAM_ZLIB, int level = Z_DEFAULT_COMPRESSION); // 有 zlib压缩(STREAM_ZLIB)和 gzip压缩(STREAM_GZIP) // level : 1~9 表示压缩的程度 /* compression levels */ // #define Z_NO_COMPRESSION 0 // #define Z_BEST_SPEED 1 // #define Z_BEST_COMPRESSION 9 // #define Z_DEFAULT_COMPRESSION (-1) //DeflatingOutputStream deflator(ofile);//默认压缩 //DeflatingOutputStream deflator(ofile, Poco::DeflatingStreamBuf::STREAM_ZLIB, 1);//最快压缩 DeflatingOutputStream deflator(ofile, Poco::DeflatingStreamBuf::STREAM_ZLIB, 9);//最大压缩 StreamCopier::copyStream(ifile, deflator); if (!ofile) //error writing output file return -2; // result: //默认压缩 Z_DEFAULT_COMPRESSION : 234K -> 67K //最快压缩 Z_BEST_SPEED : 234K -> 77K //最大压缩 Z_BEST_COMPRESSION : 234K -> 66K return 0; }
解压文件:
//解压文件 #include "Poco/InflatingStream.h" #include "Poco/StreamCopier.h" #include <fstream> using Poco::InflatingInputStream; using Poco::StreamCopier; int main() { std::ifstream ifile("F:/test.zlib", std::ios::binary); if (!ifile.is_open()) return -1; std::ofstream ofile("F:/test2.xls", std::ios::binary); if (!ofile.is_open()) return -2; InflatingInputStream inflator(ifile);//默认参数:STREAM_ZLIB 若解压gzip,用 STREAM_GZIP StreamCopier::copyStream(inflator, ofile); if (!ofile) return -3;// error writing output file return 0; }
注:gzip 压缩的文件,可以用WinRAR或7Z解压,但不知文件的后缀名。可以让输出文件名为 test.xls.gzip ,用WinRAR或7Z解压后就带文件后缀了。
- poco 正则表达式
#include "Poco/RegularExpression.h" #include <iostream> using Poco::RegularExpression; int main(int argc, char** argv) { std::string pattern = "ig"; int options = 0; options += RegularExpression::RE_CASELESS;//不区分大小写 options += RegularExpression::RE_EXTENDED;//忽略空白 RegularExpression re(pattern, options); std::string line = "Slient night, holy night. "; RegularExpression::Match mtch; if (re.match(line, mtch)) { int pos = mtch.offset;//匹配的位置 int len = mtch.length;//匹配的长度 } RegularExpression p("[0-9]+"); std::string numstr = "12345ghk89760"; std::string s; std::vector<std::string> vecStr; int n = p.extract(numstr, s); //n=1, s=12345 n = p.extract(numstr, 5, s); //n=1, s=89760 bool b = p.match(numstr); // b = false, 完全匹配时返回true b = p.match("14389274805");// b = true // 替换匹配(only first) n = p.subst(numstr, "*"); //numstr="*ghk89760" // 替换所有匹配到的内容 n = p.subst(numstr, "*", Poco::RegularExpression::RE_GLOBAL); //numstr="*ghk*" return 0; }
- poco 写日志 logger
#include "Poco/Logger.h" #include "Poco/PatternFormatter.h" #include "Poco/FormattingChannel.h" #include "Poco/ConsoleChannel.h" #include "Poco/FileChannel.h" #include "Poco/Message.h" using Poco::Logger; using Poco::PatternFormatter; using Poco::FormattingChannel; using Poco::ConsoleChannel; using Poco::FileChannel; using Poco::Message; int main(int argc, char** argv) { //FormattingChannel* pFCFile = new FormattingChannel(new PatternFormatter("%Y-%m-%d %H:%M:%S.%c %N[%P]:%s:%q:%t")); FormattingChannel* pFCFile = new FormattingChannel(new PatternFormatter("[%Y-%m-%d %H:%M:%S.%c] [%s:%p]: %t")); pFCFile->setChannel(new FileChannel("D:/sample.log")); pFCFile->open(); Logger& fileLogger = Logger::create("FileLogger", pFCFile, Message::PRIO_WARNING);//只有权限不低于指定的level,才写入 fileLogger.error("An error message");//ok fileLogger.warning("A warning message");//ok fileLogger.information("An information message");//低于PRIO_WARNING,写不上 poco_warning_f2(fileLogger, "A warning message with arguments: %d, %d", 1, 2);//ok Logger::get("FileLogger").error("Another error message");//ok return 0; } //------------------------------------------------------ enum Priority { PRIO_FATAL = 1, /// A fatal error. The application will most likely terminate. This is the highest priority. PRIO_CRITICAL, /// A critical error. The application might not be able to continue running successfully. PRIO_ERROR, /// An error. An operation did not complete successfully, but the application as a whole is not affected. PRIO_WARNING, /// A warning. An operation completed with an unexpected result. PRIO_NOTICE, /// A notice, which is an information with just a higher priority. PRIO_INFORMATION, /// An informational message, usually denoting the successful completion of an operation. PRIO_DEBUG, /// A debugging message. PRIO_TRACE /// A tracing message. This is the lowest priority. };
- poco 的 URL
#include "Poco/URI.h" #include <iostream> using Poco::URI; int main(int argc, char** argv) { URI uri1("http://www.appinf.com:81/sample?example-query#somewhere"); std::cout << "Scheme: " << uri1.getScheme() << std::endl // http << "Authority: " << uri1.getAuthority() << std::endl// www.appinf.com:81 << "Path: " << uri1.getPath() << std::endl// /sample << "Query: " << uri1.getQuery() << std::endl// example-query << "Fragment: " << uri1.getFragment() << std::endl;// somewhere URI uri2; uri2.setScheme("https"); uri2.setAuthority("www.appinf.com"); uri2.setPath("/another sample"); std::cout << uri2.toString() << std::endl; return 0; }
- poco的UUID(UUID 是 通用唯一识别码(Universally Unique Identifier))
#include "Poco/UUID.h" #include "Poco/UUIDGenerator.h" #include "Poco/Exception.h" #include <iostream> using Poco::UUID; using Poco::UUIDGenerator; using Poco::Exception; int main(int argc, char** argv) { UUID uuid; std::string arg; if (argc > 1) arg = argv[1];//arg="jook" try { if (arg == "-random") uuid = UUIDGenerator::defaultGenerator().createRandom(); else if (arg.empty()) uuid = UUIDGenerator::defaultGenerator().create(); else uuid = UUIDGenerator::defaultGenerator().createFromName(UUID::uri(), arg); std::string sRet = uuid.toString();//67440b59-4ad8-3f74-8bab-8b4ae76b4fc3 } catch (Exception& exc) { std::cerr << exc.displayText() << std::endl; return 1; } return 0; }
- poco的读写配置文件,包括ini文件、properties文件、xml文件
// ini文件 #include "Poco/AutoPtr.h" #include "Poco/Util/IniFileConfiguration.h" #include <fstream> using Poco::AutoPtr; using Poco::Util::IniFileConfiguration; int main(int argc, char** argv) { try{ const std::string path = "D:/test.ini"; AutoPtr<IniFileConfiguration> pConf(new IniFileConfiguration(path)); //注:大小写不敏感 std::string title = pConf->getString("bookinfo.Title","UnKnown");//第二个参数是默认值 std::string author = pConf->getString("bookInfo.author");//没有默认值时,若无该节点则抛异常Poco::NotFoundException //int value = pConf->getInt("BOOKinfo.price", -1);//抛异常Poco::SyntaxException 29.99 is not a integer. int value = pConf->getInt("BOOKinfo.PAGES", -1); std::string sPrice = pConf->getRawString("BOOKinfo.price", "default string"); //写入配置(注意:IniFileConfiguration修改了,但test.ini没写不进去) AutoPtr<IniFileConfiguration> pConf2(new IniFileConfiguration("test.ini")); pConf2->setString("BOOKinfo.price2", "ppp"); pConf2->setUInt("jjj", 90); } catch (Poco::Exception& e) { std::string s = e.displayText(); return -1; } return 0; }
1. ini文件
/* D:/test.ini [BookInfo] title=Harry Potter author =J.K. Rowling price= 29.99 Pages = 2345 */ // ini文件 #include "Poco/AutoPtr.h" #include "Poco/Util/IniFileConfiguration.h" #include <fstream> using Poco::AutoPtr; using Poco::Util::IniFileConfiguration; int main(int argc, char** argv) { try{ const std::string path = "D:/test.ini"; AutoPtr<IniFileConfiguration> pConf(new IniFileConfiguration(path)); //注:大小写不敏感 std::string title = pConf->getString("bookinfo.Title","UnKnown");//第二个参数是默认值 std::string author = pConf->getString("bookInfo.author");//没有默认值时,若无该节点则抛异常Poco::NotFoundException //int value = pConf->getInt("BOOKinfo.price", -1);//抛异常Poco::SyntaxException 29.99 is not a integer. int value = pConf->getInt("BOOKinfo.PAGES", -1); std::string sPrice = pConf->getRawString("BOOKinfo.price", "default string"); //写入配置(注意:IniFileConfiguration修改了,但test.ini没写不进去) AutoPtr<IniFileConfiguration> pConf2(new IniFileConfiguration("test.ini")); pConf2->setString("BOOKinfo.price2", "ppp"); pConf2->setUInt("jjj", 90); } catch (Poco::Exception& e) { std::string s = e.displayText(); return -1; } return 0; }
2. properties文件
// test.properties /* #这是注释行,<key> = <value> 或者 <key> : <value> BookInfo BookInfo.title= Harry Potter BookInfo.author =J.K. Rowling BookInfo.price: 29.99 BookInfo.Pages = 2345 key.longValue: this is a Very lo\ ng value key.string :: we are: one. key.test = tt=test path : C:\\Test.dat */ #include "Poco/AutoPtr.h" #include "Poco/Util/PropertyFileConfiguration.h" using Poco::AutoPtr; using Poco::Util::PropertyFileConfiguration; int main(int argc, char** argv) { AutoPtr<PropertyFileConfiguration> pConf; pConf = new PropertyFileConfiguration("test.properties"); try {//注意:properties中的属性名区分大小写 std::string str = pConf->getString("BookInfo.title", "Unknown");//"Harry Potter" str = pConf->getString("BookInfo","--");// "" int value1 = pConf->getInt("BookInfo.Pages", -1); // "2345" str = pConf->getString("key.string", "");//": we are: one." std::string logV = pConf->getString("key.longValue");// "this is a Very long value" std::string path = pConf->getString("path");// "C:\Test.dat" pConf->setString("key.test", "tt");//设置,但并没有写入配置文件test.properties中 pConf->save("test.properties");//真正写入配置文件 } catch (Poco::Exception& e) { std::string s = e.displayText(); return -1; } return 0; } //写入后的格式被自动整理 //写入后的 test.properties /* BookInfo: BookInfo.Pages: 2345 BookInfo.author: J.K. Rowling BookInfo.price: 29.99 BookInfo.title: Harry Potter key.longValue: this is a Very long value key.string: : we are: one. key.test: tt path: C:\\Test.dat */
3. xml配置文件
/* test.xml <?xml version="1.0" encoding="utf-8" ?> <!--this is a comment.--> <books> <book category="children" language="English"> <title>Harry Potter</title> <author> J.K. Rowling </author> <price>29.99</price> <pages>521</pages> </book> <book category="science fiction"/> <prop5 id="first">value5</prop5> <prop5 id="second">value6</prop5> <ttt>中文\</ttt> </books> */ //xml配置文件 #include "Poco/AutoPtr.h" #include "Poco/Util/XMLConfiguration.h" #include "Poco/UnicodeConverter.h" using Poco::AutoPtr; using Poco::Util::XMLConfiguration; int main(int argc, char** argv) { try{//case sensitive AutoPtr<XMLConfiguration> pConfig(new XMLConfiguration("D:/test.xml")); std::string str = pConfig->getString("book.title", "--");// "Harry Potter" int n = pConfig->getInt("book.pages", -1);//"521" str = pConfig->getString("book.author", "");//" J.K. Rowling " str = pConfig->getString("book.category", "--");//"--" str = pConfig->getString("book[@language]", "default");//"English" str = pConfig->getString("book[@category]", "default");//"children" str = pConfig->getString("book[1][@category]");//"science fiction" str = pConfig->getString("prop5[@id=first]", "--");//"value5" str = pConfig->getString("prop5[@id='second']", "--");//"value6" str = pConfig->getString("ttt", "--");// "涓枃\"("中文\"的utf8编码) std::wstring wsUnicode; Poco::UnicodeConverter::toUTF16(str, wsUnicode);//"中文\" utf8 -> Unicode(utf16) //写入 pConfig->setString("test", "12fg"); pConfig->setString("test[@attr]", "sss"); std::string sUtf8; Poco::UnicodeConverter::toUTF8(L"中文测试", sUtf8);//Unicode(utf16) -> utf8 pConfig->setString("test2", sUtf8); pConfig->save("D:/test2.xml"); } catch (Poco::Exception& e) { std::string s = e.displayText(); return -1; } return 0; } /* save后 <!--this is a comment.--> <books> <book category="children" language="English"> <title>Harry Potter</title> <author> J.K. Rowling </author> <price>29.99</price> <pages>521</pages> </book> <book category="science fiction"/> <prop5 id="first">value5</prop5> <prop5 id="second">value6</prop5> <ttt>中文\</ttt> <test attr="sss">12fg</test> <test2>中文测试</test2> </books> */
------------------
常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。
昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。