cocos文件持久化

本文介绍了Cocos2d-x中如何进行文件持久化,包括使用UserDefault进行简单数据存储,以及利用rapidjson操作JSON文件。同时,讲解了在iOS沙盒环境下如何复制文件到可读写路径进行修改,以及快速访问和操作JSON文件的方法。此外,还涉及到tinyxml2库解析和操作XML文件的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

cocos 文件持久化  

访问json文件格式

rapidjson::Document doc;

    doc.Parse<rapidjson::kParseDefaultFlags>(data.c_str());

    doc["hello”][0].AddMember("name", "zhnaghow", doc.GetAllocator());//hello为属性名  [0] hello内第一个大括号包含的内容

json文件格式:

{

    "hello":[

             {

             "id":1,

             "age":15,

             "email":"12306@136.com"

             },

             {

             "id":2,

             "age":18,

             "email":"12306@qq.com"

             }

             ],

    "xiaohong":[

                {

                "id":2,

                "age":18,

                "email":"12306@qq.com"

                }

                ]

}

    

    // 删除内容

    doc["hello"][1-1].RemoveMember("id");

UserDefault     常用于单机游戏中

void HelloWorld::userDefault(){

    // UserDefault cocos2d-x定义的一个用来存储小数据的单例类

    // 获取UserDefault单例

    auto userD = UserDefault::getInstance();

    // 设置数据

    userD->setStringForKey("username", "hello");

    userD->setStringForKey("password", "123");

    userD->flush();// 将数据写入文件中xx.xx.xx plist文件  获取路径是UserDefault.xml

    

    // 通过key得到value

    auto username = userD->getStringForKey("username").c_str();

    auto password = userD->getStringForKey("password","no this key").c_str();

    log("username:%s",username);

    log("password:%s",password);

    int a = 0;

    userD->setIntegerForKey("int", a);

    userD->setBoolForKey("firstlogin", true);

    

    auto firstLogin = userD->getStringForKey("firstlogin").c_str();

    if (firstLogin) {

        log("yes");

    }else{

        log("no");

    }

    // 获取xml文件路径(xml相当于一个转换文件,虚拟的)

    auto path = userD->getXMLFilePath().c_str();

    log("Path:%s",path);

    // 结果xml不存在,结果保存在library文件夹下的  包名.plist

    if (userD->isXMLFileExist()) {

        log("yes");

    }else{

        log("no");

    }

}

文件操作copy

之所以单独将拷贝拿出来是因为iOS的沙盒机制,程序员和 用户是没有权限访问app文件内容的

所以需要将这个文件的内容拷贝一份到可读写路径(沙盒-Documents)下,进行修改等操作

void HelloWorld::copyFile(const char * filename){

    // app路径下的文件是无法修改的,需要将这个文件的内容拷贝一份到可读写路径(沙盒-Documents)下

    // 获取文件的APP路径

    auto app_path = FileUtils::getInstance()->fullPathForFilename(filename);

    log("app_pat:%s",app_path.c_str());

    // 获取可读写路径

    auto writeable_path = FileUtils::getInstance()->getWritablePath();

    log("writeable_path:%s",writeable_path.c_str());

    

    // 拷贝文件

    // app路径下的文件内容读取到字符串fileData

    std::string fileData = FileUtils::getInstance()->getStringFromFile(app_path);

    // 修改可读写路径

    writeable_path += filename;

    // 打开可读写路径下的文件(如果有就打开,没有则创建后再打开),二进制写入形式

    FILE * file = fopen(writeable_path.c_str(), "wb");

    if (file) {

        fputs(fileData.c_str(), file);// 内容写到文件中

        fclose(file);// 关闭文件

    }

//     输出文件内容

    log("file/Data:\n%s",fileData.c_str());    

}

快速访问、操作json文件

需要引入以下头文件

#include "json/document.h"

#include "json/rapidjson.h"

#include "json/stringbuffer.h"

#include "json/writer.h"


void HelloWorld::rapidJsonTest(const char * filename){

    auto writeable_path = FileUtils::getInstance()->getWritablePath();

    writeable_path += filename;

    auto data = FileUtils::getInstance()->getStringFromFile(writeable_path.c_str());

    

    rapidjson::Document doc;

    doc.Parse<rapidjson::kParseDefaultFlags>(data.c_str());

    

    if (doc.HasParseError()) {

        log("文件解析失败");

        return;

    }

    doc["hello"][1-1].AddMember("name", "zhnaghow", doc.GetAllocator());

    

    // 删除内容

    doc["hello"][1-1].RemoveMember("id");

    

    rapidjson::StringBuffer buffer;// 缓冲区

    rapidjson::Writer<rapidjson::StringBuffer>writer(buffer);// 写入器

    doc.Accept(writer);

    

    FILE * file = fopen(writeable_path.c_str(), "wb");

    if (file) {

        fputs(buffer.GetString(), file);

        fclose(file);

    }

    

    log("modifieds:");

    log("%s",FileUtils::getInstance()->getStringFromFile(writeable_path).c_str());

}

访问操作XML文件

首先要包含头文件include“tinyxml2/tinyxml2.h”

      命名空间using namespace  tinyxml2;

普通.xml文件的格式:

<?xml version="1.0" encoding="utf-8" ?>

<Root>

    <user id="001">

        <admin sex="man">

            <name>fred</name>

            <password>150150</password>

            <age>22</age>

        </admin>

        <admin sex="woman">

            <name>yucai</name>

            <password>123456</password>

            <age>21</age>

        </admin>    

    </user> 

</Root>

首先是拷贝文件,将.xml文件拷贝至沙盒目录中(有读写权限),后续做增删查改的操作

void HelloWorld::tinyxmlTest(const char * filename){

   // 获取文件可读写路径

    std::string path = FileUtils::getInstance()->getWritablePath();

    path+=filename;

    

    tinyxml2::XMLDocument * doc = new XMLDocument();

    XMLError error = doc->LoadFile(path.c_str());

    if (error!=0) {

        log("解析失败");

        return;

    }

    log("%d",error);

    

    // 获得root节点

    XMLElement * root = doc->RootElement();

    // 获得root下的user节点(层级关系)

    XMLElement * user = root->FirstChildElement();

    // 获取user的属性

    const XMLAttribute * user_id =  user->FirstAttribute();

    log("user_id:%s",user_id->Value());// 输出属性值

    // 返回user下的第一个admin标签

    XMLElement * admin1 = user->FirstChildElement();

    XMLElement * admin2 = admin1->NextSiblingElement();

    

    const XMLAttribute * admin1_sex =  admin1->FirstAttribute();

    const XMLAttribute * admin2_sex =  admin2->FirstAttribute();

    

    log("admin1_attribute:%s",admin1_sex->Value());

    log("admin2_attribute:%s",admin2_sex->Value());

    

    // 得到admin下的name

    XMLElement * name = admin1->FirstChildElement();

    log("name_value:%s",name->Value());

    log("name_text:%s",name->GetText());

    // 根据父节点删除子节点属性

    XMLElement * age = name->NextSiblingElement();

    admin1->DeleteChild(age);

    

    

    // 添加<emaile QQ = "yes">123546@qq.com</emaile> 添加到admin2

    XMLElement * newElement = doc->NewElement("email");// 创建标签添加value

    // 创建标签,注意这里使用的是doc(Document对象)调用NewElement()

    XMLText * newText = doc->NewText("12346@qq.com");// 添加Text

    newElement->SetAttribute("QQ", "yes"); // 添加属性

    newElement->LinkEndChild(newText);

    admin2->LinkEndChild(newElement);

    

    // 修改标签的内容 password

    // 获取<password>标签

    XMLElement * passworld = admin2->FirstChildElement()->NextSiblingElement();

    passworld->SetValue("密码");

    passworld->FirstChild()->ToText()->SetValue("10086");

    

    // 保存修改过的文件

    doc->SaveFile(path.c_str());

    

    

    delete doc;

    log("%s",FileUtils::getInstance()->getStringFromFile(path).c_str());

}




                                

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值