文件操作2之plist文件操作
DionysosLai(906391500@qq.com) 2015/1/19
Plist文件属于一种比较常见文件格式,通常用来存储用户设置,也可以用于存储捆绑信息,原先是用在Mac中,后来推广到其他系统中。概况来说,Plist文件是以.plist格式结尾,xml格式的一种文件,读写方式比较基本以’键’= ‘值’方式对应。
本文系统的介绍基于cocos2dx-2.3版本的plist文件读写细节,希望通过本文,对其他plist文件能够达到自由读取目的。
plist 资源文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>metadata</key>
<dict>
<key>format</key>
<integer>1</integer>
<key>ptm_ratio</key>
<real>32</real>
</dict>
<key>bodies</key>
<dict>
<key>PIC_UI_HG</key>
<dict>
<key>anchorpoint</key>
<string>{ 0.0000,0.0000 }</string>
<key>fixtures</key>
<array>
<dict>
<key>density</key> <real>2</real>
<key>friction</key> <real>0</real>
<key>restitution</key> <real>0</real>
<key>filter_categoryBits</key> <integer>1</integer>
<key>filter_groupIndex</key> <integer>0</integer>
<key>filter_maskBits</key> <integer>65535</integer>
<key>isSensor</key> <true/>
<key>id</key> <string></string>
<key>fixture_type</key> <string>POLYGON</string>
<key>POLYGON</key>
<array>
<array>
<string>{ 97.000,126.000 }</string>
<string>{ 98.000,112.000 }</string>
<string>{ 110.000,100.000 }</string>
<string>{ 103.000,125.000 }</string>
</array>
<array>
<string>{ 98.000,112.000 }</string>
<string>{ 78.000,100.000 }</string>
<string>{ 56.000,65.000 }</string>
<string>{ 71.000,23.000 }</string>
<string>{ 99.000,54.000 }</string>
<string>{ 110.000,80.000 }</string>
<string>{ 110.000,100.000 }</string>
</array>
<array>
<string>{ 56.000,65.000 }</string>
<string>{ 26.000,50.000 }</string>
<string>{ 4.000,30.000 }</string>
<string>{ 0.000,16.000 }</string>
<string>{ 6.000,4.000 }</string>
<string>{ 23.000,1.000 }</string>
<string>{ 45.000,6.000 }</string>
<string>{ 71.000,23.000 }</string>
</array>
</array>
</dict>
</array>
</dict>
</dict>
</dict>
</plist>
以上数据是从一个box2d物理对象的plist文件中抽取出来,将其命名为”test.plist”。
第一步:读取plist文件
读取plist文件,由于plist是采用’键’=’值’格式,因此读取其文件,基本采用CCDictionary类读取,代码如下:
/// 先读取plist文件
CCDictionary *dict = CCDictionary::createWithContentsOfFile("test.plist");
CCAssert(dict != NULL, "file not found!");
CCAssert(dict->count() != 0, "file is empty or not existing!");
第二步:读取第一个dict下内容
‘test.plist’文件,首先包括了两个’字典’,第一个字典其’键’key 值为’ metadata’,我们先通过读取第一个dict下内容,学会如何读取int和float两种类型值,代码如下:
/// 读取第一个dict下的“metadata”内容
CCDictionary *metadataDict = (CCDictionary *)dict->objectForKey("metadata");
int format = static_cast<CCString *>(metadataDict->objectForKey("format"))->intValue(); ///< 读取“format”值,是一个integer类型
float ptm_ratio = static_cast<CCString *>(metadataDict->objectForKey("ptm_ratio"))->floatValue(); ///< 读取“format”值,是一个real值
第三步:学会轮询dict值
第二个’键’:’ bodies’下只有一个dict(其下第二层dict不算),但这里我们当做其包含多个dict来处理,学会轮询dict值,由于预先知道是轮询dict,因此知道其类型为CCDictElement,代码如下:
/// 读取第二个dict下的“bodies”内容
CCDictionary *bodiesDict = (CCDictionary *)dict->objectForKey("bodies");
CCDictElement *dictElem;
std::string bodyName;
CCDictionary *bodyData;
CCDICT_FOREACH(bodiesDict, dictElem) ///< 轮询bodies下多个dict值,test示例中,只有一个
{
bodyData = (CCDictionary*)dictElem->getObject(); ///< 获取当前dict内容
bodyName = dictElem->getStrKey(); ///< map的key
......
......
......
}
第四步:学会读取队列array值、bool、string值
从’test.plist’文件中,可以看出,’bodies’下包含多个array队列,因此我们这一步工作是,如何读取array中的值,由于array中包含多种类型值,因此采用CCObject类型,同时这里面包含多种类型,一一读取这些值,学会读取各种类型值,代码如下:
const char* pointch = static_cast<CCString *>(bodyData->objectForKey("anchorpoint"))->getCString(); ///< 读取“anchorpoint”,是个string,转换成char*,与下面比较
CCArray *fixtureList = (CCArray*)(bodyData->objectForKey("fixtures")); ///< 读取"fixtures",是一个array
CCObject *arrayElem;
CCARRAY_FOREACH(fixtureList, arrayElem)
{
CCDictionary* fixtureData = (CCDictionary*)arrayElem; ///< 获取当前array内容
/// 读取一些值
float density = static_cast<CCString *>(fixtureData->objectForKey("density"))->floatValue();
int categoryBits = static_cast<CCString *>(fixtureData->objectForKey("filter_categoryBits"))->intValue();
bool isSensor = static_cast<CCString *>(fixtureData->objectForKey("isSensor"))->boolValue();
std::string fixtureType = static_cast<CCString *>(fixtureData->objectForKey("fixture_type"))->m_sString;
/// 下面依然是一个array
CCArray *polygonsArray = (CCArray *)(fixtureData->objectForKey("POLYGON"));
CCObject *dicArrayElem;
CCARRAY_FOREACH(polygonsArray, dicArrayElem) ///< 第二个array
{
….
}
}
综上,plist文件读写示例完毕,demo下载地址:https://github.com/DionysosLai/FileReadDemo
希望对大家有点用处。