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());
}