Cococs2d-x 之文件操作

字符串操作

cocos 中用到三种字符串,C 字符串char*,C++ 字符串std::string和cocos定义的字符串。
C 字符串是最基本的字符串,C++ 字符串是对 C 字符串的二次封装,cocos 字符串是对 C 和 C++ 字符串的再次封装,它继承 Ref 和 clonable,在 cocos 中是一个对象,并引入计数引用技术。

    //c字符串与c++字符串
    char* cstr = "helloworld";
    log("str len: %d",strlen(cstr));
    log("c str: %s",cstr);
    //c字符串转c++字符串
    std::string* ccstr= new std::string(cstr);
    //c++字符串转c字符串
    log("c++ str: %s",ccstr->c_str());

    //c字符串与cocos字符串
    //c字符串转cocos字符串
    __String* cocstr = __String::createWithFormat("%s", cstr);
    //cocos字符串转c字符串
    log("cocos str: %s",cocstr->getCString());

    //c++字符串与cocos字符串
    //c++字符串转cocos字符串
    cocstr = __String::create(*ccstr);
    log("cocos str: %s", cocstr->getCString());

    //字符串操作
    std::string str=StringUtils::format("%3d %3.2f %c %s", 12, 3.1425926, 'a', "linjinxin");
    log(str.c_str());

文件读写操作

    //目录操作
    //获得系统可写路径
    log("%s", FileUtils::getInstance()->getWritablePath());
    //获取文件完整路径
    log("%s", FileUtils::getInstance()->fullPathForFilename("data.txt").c_str());
    //获取文件相对于特定文件夹的完整路径
    log("%s", FileUtils::getInstance()->fullPathFromRelativeFile("data.txt", FileUtils::getInstance()->getWritablePath()).c_str());

    //读文件
    Data data = FileUtils::getInstance()->getDataFromFile(FileUtils::getInstance()->fullPathForFilename("data.txt").c_str());
    log("%s", data.getBytes());
    data = FileUtils::getInstance()->getDataFromFile(FileUtils::getInstance()->fullPathFromRelativeFile("data.txt",FileUtils::getInstance()->getWritablePath()).c_str());
    log("%s", data.getBytes());

    //写文件
    //FILE* f = fopen(FileUtils::getInstance()->fullPathForFilename("data.txt").c_str(), "w+");
    FILE* f = fopen("data.txt", "w");
    fprintf(f, "hello cocos2d-x in local resources!");
    fclose(f);
    f = fopen(FileUtils::getInstance()->fullPathFromRelativeFile("data.txt", FileUtils::getInstance()->getWritablePath()).c_str(), "w");
    fprintf(f, "hello cocos2d-x in system path!");
    fclose(f);

各种文件操作

首选项数据

每个cocos项目会在系统可写目录下创建一个UserDefault.xml文件,用于保存少量的游戏数据,程序员无需操作文件,只需调用简单的API即可对这些数据进行读写。

    //首选项数据
    str = UserDefault::getInstance()->getStringForKey("name", "no find");
    log("name:%s", str.c_str());
    UserDefault::getInstance()->setStringForKey("name", "linjinxin");
    UserDefault::getInstance()->setIntegerForKey("age", 21);
    str = UserDefault::getInstance()->getStringForKey("name", "no find");
    auto age = UserDefault::getInstance()->getIntegerForKey("age", 18);
    log("name:%s,age:%d", str.c_str(), age);
配置文件

cocos中有一个全局的Configuration,包含一些 openGL 变量的Configuration。我们也可以用这个文件来读写一些配置。

    //配置文件
    Configuration* config = Configuration::getInstance();
    config->loadConfigFile("config.plist");
    log("name:%s", config->getValue("name").asString().c_str());
    log("gate:%d", config->getValue("gate", Value(0)));
    config->setValue("gate", Value(5));
    log("gate:%d", config->getValue("gate", Value(0)));
Plist文件读写

Plist 文件全称 Property List,即属性列表,是 ios 采用的配置文件格式,cocos2d-x 发展自 cocos,而 cocos 最早是运行在 ios 上的,所以cocos2d-x 仍支持 plist 文件的操作。plist 文件的本质是是xml,再结合的 json 的特点,根结点有数组和字典两种方式。使用Plist文件可解决cocos2d中的中文乱码问题。
根结点为字典的格式:

<?xml version="1.0" encoding="utf-8"?>
<plist version="1.0">
    <dict>
        <key>name</key>
    <string>林锦新</string>
    <key>age</key>
    <string>18</string>
    </dict>
</plist>

读取代码:

ValueMap vm = FileUtils::getInstance()->getValueMapFromFile("dict.plist");
log("%s %d", vm["name"].asString().c_str(),vm["age"].asInt());

根结点为数组的格式:

<?xml version="1.0" encoding="utf-8"?>
<plist version="1.0">
    <array>
    <string>林锦新</string> 
    <string>18</string>
    </array>
</plist>

读取代码:

ValueVector vv=FileUtils::getInstance()->getValueVectorFromFile("arr.plist");
log("%s %d", vv[0].asString().c_str(),vv[1].asInt());
xml文件读写

xml是一种应用十分广泛的数据存储格式,像上面的PList文件,其本质也是xml文件。每个xml文件有且只有一个根结点,有多个根结点只识别第一个结点作为根结点,其它结点被忽略。xml文件由层级关系的父子结点及结点属性组成。

<?xml version="1.0" encoding="utf-8"?>
<data>
  <p name="zhangshan" age="18">
    <address province="广东省" city="广州市"/>
  </p>
  <p name="lishi" age="20"/>
</data>

cocos2d要解析和创建xml文件必须先引入一个库

#include "tinyxml2/tinyxml2.h"

下面解析xml文件,采用递归的方式从根结点开始遍历所有的子结点。

//xml文件解析
tinyxml2::XMLDocument xmlDoc;
xmlDoc.Parse(FileUtils::getInstance()->getStringFromFile("data.xml").c_str());
//获得根结点
tinyxml2::XMLElement *root = xmlDoc.RootElement();
//xml解析
xmlParse(root);

//xml解析
void HelloFile::xmlParse(tinyxml2::XMLElement* root) {
    //遍历当前结点的子结点
    for (tinyxml2::XMLElement* e = root->FirstChildElement(); e; e = e->NextSiblingElement()) {
        std::string str;
        //获得结点名称
        str = StringUtils::format("%s=", e->Name());
        //遍历当前结点的属性
        for (const tinyxml2::XMLAttribute* attr = e->FirstAttribute(); attr; attr = attr->Next()) {
            str = str + "(" + attr->Name() + "=" + attr->Value() + ");";
        }
        log("%s", str.c_str());
        //递归遍历子结点
        xmlParse(e);
    }
}

下面再看一下xml文件的创建

//创建xml文件
void HelloFile::xmlCreate() {
    //声明xml文档
    tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
    //声明xml文件头
    tinyxml2::XMLDeclaration* pDec = doc->NewDeclaration("xml version=\"1.0\" encoding=\"utf-8\"");
    //将文件头链接到文件
    doc->LinkEndChild(pDec);
    //声明根结点
    tinyxml2::XMLElement* root = doc->NewElement("root");
    //为根结点添加属性
    root->SetAttribute("type", "game");
    root->SetAttribute("version", 5);
    //声明子结点并添加到根结点
    tinyxml2::XMLElement* first = doc->NewElement("p");
    first->SetAttribute("name", "zhangshan");
    tinyxml2::XMLElement* second = doc->NewElement("q");
    second->SetAttribute("name", "lishi");
    root->InsertFirstChild(first);
    root->InsertAfterChild(first, second);
    tinyxml2::XMLElement* grandson = doc->NewElement("address");
    grandson->SetAttribute("city", "guangzhou");
    first->InsertFirstChild(grandson);
    //将根结点添加到文档
    doc->InsertEndChild(root);
    //保存文档
    //文件会保存在Resource目录下
    doc->SaveFile("newData.xml");
    //释放内存
    delete doc;
}

保存后的文件内容:

<?xml version="1.0" encoding="utf-8"?>
<root type="game" version="5">
    <p name="zhangshan">
        <address city="guangzhou"/>
    </p>
    <q name="lishi"/>
</root>

使用xml文件也可以解决 cocos2d 中的中文乱码问题。

json文件读写

json文件有两种存储方式,一种是根结点是数组,一种是根结点为对象(集合)。
cocos中读写json文件要先引入下列库:

#include "json/rapidjson.h"
#include "json/document.h"
#include "json/stringbuffer.h"
#include "json/writer.h"

创建json文件(数组格式)

//以数组格式创建json
void HelloFile::jsonCreateWithArray() {
    //声明json文档
    rapidjson::Document doc;
    //设置json文档格式为数组
    doc.SetArray();
    //声明Allocator
    rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();

    //声明json对象
    rapidjson::Value obj1(rapidjson::kObjectType);
    rapidjson::Value obj2(rapidjson::kObjectType);
    //声明json数组
    rapidjson::Value arr1(rapidjson::kArrayType);

    //为对象赋值
    obj1.AddMember("name", "zhangshan",allocator);
    obj1.AddMember("age", 18, allocator);
    obj2.AddMember("name", "Lishi",allocator);
    //为数组添加元素
    arr1.PushBack("hero", allocator);
    arr1.PushBack("moster", allocator);
    arr1.PushBack("judge", allocator);

    //将所有对象和数组添加到根数组
    doc.PushBack(obj1, allocator);
    doc.PushBack(obj2, allocator);
    doc.PushBack(arr1, allocator);

    //声明字符缓冲
    rapidjson::StringBuffer buffer;
    //声明写入器
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    //写入json文档
    doc.Accept(writer);

    //保存到文件
    FILE* f = fopen("newArray.json", "w");
    fprintf(f, StringUtils::format("%s", buffer.GetString()).c_str());
    fclose(f);
}

文件内容:

<pre name="code" class="html">[
  {
    "name": "zhangshan",
    "age": 18
  },
  { "name": "Lishi" },
  [ "hero", "moster", "judge" ]
]

创建json文件(对象格式)

//以对象格式创建json
void HelloFile::jsonCreateWithObject() {
    //声明json文档
    rapidjson::Document doc;
    //设置根结点为对象
    doc.SetObject();
    //声明Allocator
    rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();

    //声明json对象
    rapidjson::Value obj1(rapidjson::kObjectType);
    rapidjson::Value obj2(rapidjson::kObjectType);
    //声明json数组
    rapidjson::Value arr1(rapidjson::kArrayType);

    //为对象赋值
    obj1.AddMember("name", "zhangshan", allocator);
    obj1.AddMember("age", 18, allocator);
    obj2.AddMember("name", "Lishi", allocator);
    //为数组添加元素
    arr1.PushBack("hero", allocator);
    arr1.PushBack("moster", allocator);
    arr1.PushBack("judge", allocator);

    //将所有对象和数组添加到根数组
    doc.AddMember("character1", obj1, allocator);
    doc.AddMember("character2", obj2, allocator);
    doc.AddMember("statement", arr1, allocator);

    //声明字符缓冲
    rapidjson::StringBuffer buffer;
    //声明写入器
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    //写入json文档
    doc.Accept(writer);

    //保存到文件
    FILE* f = fopen("newObject.json", "w");
    fprintf(f, StringUtils::format("%s", buffer.GetString()).c_str());
    fclose(f);
}

文件内容:

{
  "character1": {
    "name": "zhangshan",
    "age": 18
  },
  "character2": { "name": "Lishi" },
  "statement": [ "hero", "moster", "judge" ]
}

解析数组格式,我们解析上面创建的文件:

//解析数组格式的json文件
void HelloFile::jsonParseWithArray() {
    rapidjson::Document doc;
    doc.Parse(FileUtils::getInstance()->getStringFromFile("newArray.json").c_str());
    log("%s", doc[(int)0]["name"].GetString());
    log("%d", doc[(int)0]["age"].GetInt());
    log("%s", doc[2][0].GetString());
}

解析 对象格式,我们解析上面创建的文件:

//解析对象格式的json文件
void HelloFile::jsonParseWithObject() {
    rapidjson::Document doc;
    doc.Parse(FileUtils::getInstance()->getStringFromFile("newObject.json").c_str());
    log("%s", doc["character1"]["name"].GetString());
    log("%d", doc["character1"]["age"].GetInt());
    log("%s", doc["statement"][0].GetString());
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值