说明:本文所论述内容均基于cocos2dx 3.0 版本。

1、UserDefault

它是cocos2d-x用来存取基本数据类型用的。保存为XML文件格式。

查看CCUserDefault文件,可以看出,文件名默认为UserDefault.xml。在win32平台,Debug下,该文件在Debug.win32文件夹内。如果该文件不存在,则会创建新文件。

1 // root name of xml
2 #define USERDEFAULT_ROOT_NAME    "userDefaultRoot"
3
4 #define XML_FILE_NAME "UserDefault.xml"

用UserDefault

操作方式比较简单:

主要方法:(和java的map很像,键值对,应该很容易懂的)

1 void    setBoolForKey(const char* pKey, bool value);
2 void    setIntegerForKey(const char* pKey, int value);
3 void    setFloatForKey(const char* pKey, float value);
4 void    setDoubleForKey(const char* pKey, double value);
5 void    setStringForKey(const char* pKey, const std::string & value);

通过键读取数据,如果键不存在,可以设置一个defaultValue返回自己想要的值。

1 bool    getBoolForKey(const char* pKey, bool defaultValue = false);
2 int    getIntegerForKey(const char* pKey, int defaultValue = 0);
3 float    getFloatForKey(const char* pKey, float defaultValue=0.0f);
4 double    getDoubleForKey(const char* pKey, double defaultValue=0.0);
5 std::string    getStringForKey(const char* pKey, const std::string & defaultValue = "");

UserDefault封装了对XML文件的处理,提供了简单操作文件的方法,但是不足之处在于固定的文件夹,固定的文件名称。有限的数据类型。

2、FileUtils

 static FileUtils* getInstance();//获取FileUtils类的实例   

在cocos2d-x中,文件读写其实直接使用c/c++中的文件读写操作方法,但是,在实际运用中,由于移动客户端读写文件需要相应的权限,所以读写文件就需要先指定文件的路径,我们不需要获取绝对路径,只需要获取相对路径就行,因为cocos2d-x底层已经做了相应各个平台的处理.

std::string fullPathForFilename(const std::string &filename);//获取文件的完整路径  

std::string getStringFromFile(const std::string& filename);//读取文件中的字符串

Data getDataFromFile(const std::string& filename);//获取文件数据 

可以看下Data类:

 1 class CC_DLL Data
 2 {
 3 public:
 4     static const Data Null;
 5     //构造函数
 6     Data();
 7     Data(const Data& other);
 8     Data(Data&& other);
 9     ~Data();
10     // 重载符号
11     Data& operator= (const Data& other);
12     Data& operator= (Data&& other);
13
14     unsigned char* getBytes() const;//获取数据
15     ssize_t getSize() const;//尺寸
16     void copy(unsigned char* bytes, const ssize_t size);//从bytes复制
17     void fastSet(unsigned char* bytes, const ssize_t size);//从bytes快速set,使用后bytes将不能在外部使用
18     void clear();//清除
19     bool isNull() const;//判空
20 private:
21     void move(Data& other);
22 private:
23     unsigned char* _bytes;
24     ssize_t _size;
25 };

unsigned char* getFileDataFromZip(const std::string& zipFilePath, const std::string& filename, ssize_t *size);//读取压缩文件数据(zip格式)

如果读取成功size中会返回文件的大小,否则返回0。

如果我们通过setSearchPaths()设置搜索路径("/mnt/sdcard/", "internal_dir/"),然后通过setSearchResolutionsOrder()设置子区分路径("resources-ipadhd/", "resources-ipad/", "resources-iphonehd")。如果搜索文件名为'sprite.png' 那么会先在文件查找字典中查找key: sprite.png -> value: sprite.pvr.gz,然后搜索文件'sprite.pvr.gz'如下顺序:

1              /mnt/sdcard/resources-ipadhd/sprite.pvr.gz      (if not found, search next)
2              /mnt/sdcard/resources-ipad/sprite.pvr.gz        (if not found, search next)
3              /mnt/sdcard/resources-iphonehd/sprite.pvr.gz    (if not found, search next)
4              /mnt/sdcard/sprite.pvr.gz                       (if not found, search next)
5              internal_dir/resources-ipadhd/sprite.pvr.gz     (if not found, search next)
6              internal_dir/resources-ipad/sprite.pvr.gz       (if not found, search next)
7              internal_dir/resources-iphonehd/sprite.pvr.gz   (if not found, search next)
8              internal_dir/sprite.pvr.gz                      (if not found, return "sprite.png")

If the filename contains relative path like "gamescene/uilayer/sprite.png",
and the mapping in fileLookup dictionary contains `key: gamescene/uilayer/sprite.png -> value: gamescene/uilayer/sprite.pvr.gz`.
The file search order will be:

/mnt/sdcard/gamescene/uilayer/resources-ipadhd/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/gamescene/uilayer/resources-ipad/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/gamescene/uilayer/resources-iphonehd/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/gamescene/uilayer/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/resources-ipadhd/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/resources-ipad/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/resources-iphonehd/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/sprite.pvr.gz (if not found, return "gamescene/uilayer/sprite.png")

If the new file can't be found on the file system, it will return the parameter filename directly.

如果找到返回完整路径,没找到返回'sprite.png'。

void loadFilenameLookupDictionaryFromFile(const std::string &filename);//从文件导入文件名查找字典

文件为plist格式如下:

 1    /**
 2      * Loads the filenameLookup dictionary from the contents of a filename.
 3      *
 4      * @note The plist file name should follow the format below:
 5      *
 6      * @code
 7      * <?xml version="1.0" encoding="UTF-8"?>
 8      * <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 9      * <plist version="1.0">
10      * <dict>
11      *     <key>filenames</key>
12      *     <dict>
13      *         <key>sounds/click.wav</key>
14      *         <string>sounds/click.caf</string>
15      *         <key>sounds/endgame.wav</key>
16      *         <string>sounds/endgame.caf</string>
17      *         <key>sounds/gem-0.wav</key>
18      *         <string>sounds/gem-0.caf</string>
19      *     </dict>
20      *     <key>metadata</key>
21      *     <dict>
22      *         <key>version</key>
23      *         <integer>1</integer>
24      *     </dict>
25      * </dict>
26      * </plist>
27      * @endcode
28      * @param filename The plist file name.
29      *
30      @since v2.1
31      * @js loadFilenameLookup
32      * @lua loadFilenameLookup
33      */

void setFilenameLookupDictionary(const ValueMap& filenameLookupDict);//从ValueMap中设置文件名查找字典

ValueMap的定义:

1 typedef std::unordered_map<std::string, Value> ValueMap;

std::string fullPathFromRelativeFile(const std::string &filename, const std::string &relativeFile);//获取相对应文件的完整路径

e.g. filename: hello.png, pszRelativeFile: /User/path1/path2/hello.plist   Return: /User/path1/path2/hello.pvr (If there a a key(hello.png)-value(hello.pvr) in FilenameLookup dictionary. )

void setSearchResolutionsOrder(const std::vector<std::string>& searchResolutionsOrder);//设置子搜索区分路径

见fullPathForFilename()。

void addSearchResolutionsOrder(const std::string &order);//增加子搜索路径

const std::vector<std::string>& getSearchResolutionsOrder();//获取子搜索区分路径

void setSearchPaths(const std::vector<std::string>& searchPaths);//设置搜索路径

见fullPathForFilename()。

void addSearchPath(const std::string & path);//增加搜索路径

const std::vector<std::string>& getSearchPaths() const;//获取搜索路径

std::string getWritablePath();//获取一个可写入文件的路径

经过测试在win32平台上,debug版本返回的是程序文件所在的路径,release返回的是“我的文档”路径。

bool isFileExist(const std::string& filePath);//判断文件是否存在

经过测试在win32平台上,如果路径中包含中文字符会找不到文件。所以可以自己写个。

bool isAbsolutePath(const std::string& path);判断是否为绝对路径

 

void setPopupNotify(bool notify);

bool isPopupNotify();

Sets/Gets 当文件加载失败时弹出messagebox.

ValueMap getValueMapFromFile(const std::string& filename);//从文件获取ValueMap

bool writeToFile(ValueMap& dict, const std::string& fullPath);//写入一个ValueMap数据到plist格式文件

ValueVector getValueVectorFromFile(const std::string& filename);//从文件获取ValueVector

ValueVector定义:

1 typedef std::vector<Value> ValueVector;

函数也就这些了,还没有写demo代码,写好了贴过来。

3.SQLite

4、plist文件读写

在cocos2d-x中,对于plist文件,既可以读取,也可以进行写入的操作;下面先来看一个plist文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"/>
 3
 4 <plist version="1.0">
 5     <dict>
 6         <key>string element key</key>
 7         <string>string element value</string>
 8         <key>array</key>
 9         <array>
10             <dict>
11                 <key>string in dictInArray key 0</key>
12                 <string>string in dictInArray value 0</string>
13                 <key>string in dictInArray key 1</key>
14                 <string>string in dictInArray value 1</string>
15             </dict>
16             <string>string in array</string>
17             <array>
18                 <string>string 0 in arrayInArray</string>
19                 <string>string 1 in arrayInArray</string>
20             </array>
21         </array>
22         <key>dictInDict, Hello World</key>
23         <dict>
24             <key>string in dictInDict key</key>
25             <string>string in dictInDict value</string>
26             <key>bool</key>
27             <true/>
28             <key>integer</key>
29             <integer>1024</integer>
30             <key>float</key>
31             <real>1024.1024170</real>
32             <key>double</key>
33             <real>1024.1230000000000000</real>
34         </dict>
35     </dict>
36 </plist>

View Code

先不看上面的plist文件到底有些什么内容;实际上它是由下一段代码生成的。

 1 auto root = Dictionary::create();
 2     auto string = String::create("string element value");
 3     root->setObject(string, "string element key"); // 添加一个键值对
 4
 5     auto array = Array::create();  // 创建一个array
 6
 7     auto dictInArray = Dictionary::create();
 8     dictInArray->setObject(String::create("string in dictInArray value 0"), "string in dictInArray key 0");
 9     dictInArray->setObject(String::create("string in dictInArray value 1"), "string in dictInArray key 1");
10     array->addObject(dictInArray); // 往数组中添加一个键值对
11
12     array->addObject(String::create("string in array")); // 往数组中添加一个字符串
13
14     auto arrayInArray = Array::create();
15     arrayInArray->addObject(String::create("string 0 in arrayInArray"));
16     arrayInArray->addObject(String::create("string 1 in arrayInArray"));
17     array->addObject(arrayInArray); // 往数组中添加一个数组
18
19     root->setObject(array, "array");
20
21     auto dictInDict = Dictionary::create();
22     dictInDict->setObject(String::create("string in dictInDict value"), "string in dictInDict key");
23
24     //add boolean to the plist
25     auto booleanObject = Bool::create(true);
26     dictInDict->setObject(booleanObject, "bool");
27
28     //add interger to the plist
29     auto intObject = Integer::create(1024);
30     dictInDict->setObject(intObject, "integer");
31
32     //add float to the plist
33     auto floatObject = Float::create(1024.1024f);
34     dictInDict->setObject(floatObject, "float");
35
36     //add double to the plist
37     auto doubleObject = Double::create(1024.123);
38     dictInDict->setObject(doubleObject, "double");
39
40     root->setObject(dictInDict, "dictInDict, Hello World");
41 // end with /
42     std::string writablePath = FileUtils::getInstance()->getWritablePath();
43     std::string fullPath = writablePath + "text.plist";
44     if(root->writeToFile(fullPath.c_str()))
45         log("see the plist file at %s", fullPath.c_str());
46     else
47         log("write plist file failed");
48
49     // 读取上面创建的内容
50     auto loadDict = __Dictionary::createWithContentsOfFile(fullPath.c_str());
51     auto loadDictInDict = (__Dictionary*)loadDict->objectForKey("dictInDict, Hello World");
52     auto boolValue = (__String*)loadDictInDict->objectForKey("bool");
53     CCLOG("%s",boolValue->getCString());
54     auto floatValue = (__String*)loadDictInDict->objectForKey("float");
55     CCLOG("%s",floatValue->getCString());
56     auto intValue = (__String*)loadDictInDict->objectForKey("integer");
57     CCLOG("%s",intValue->getCString());
58     auto doubleValue = (__String*)loadDictInDict->objectForKey("double");
59     CCLOG("%s",doubleValue->getCString());

View Code

因此可以看出,对符合一定格式的plist文件,可以通过Dictionary进行操作。cocos2dx 3.0 的Dictionary,可以实现对Array,Dictionary,Integer,String,Bool等基础数据类型进行读写。

下面再来看另一种读取方式: 假定plist文件如下;

1 <plist version="1.0">
2 <dict>
3     <key>name</key>
4     <string>Ls</string>
5     <key>isgirl</key>
6     <false/>
7 </dict>
8 </plist>

View Code

读取方式二,这种方法是借助VectorMap来进行读的:

1  FileUtils * fu = FileUtils::getInstance();
2     ValueMap vm = fu->getValueMapFromFile("Info.plist");
3     log("%s", vm["name"].asString().c_str()); // 读取string -->Ls
4     bool bl = vm["isgirl"].asBool(); // 读取bool -->0
5     log("%d", bl);

View Code

如果文件节点也是一个ValueMap,则可以通过xm["xx"].asValueMap()将节点转换为ValueMap;如果根节点为数组也可能直接通过ValueVector.getValueVectorFromFile("xx")读取数据;

5、xml文件读取

 1 FileUtils * fu = FileUtils::getInstance();
 2     auto doc = new tinyxml2::XMLDocument();
 3     doc->Parse(fu->getStringFromFile("data.xml").c_str());
 4     auto root = doc->RootElement();
 5     for (auto e = root->FirstChildElement(); e; e = e->NextSiblingElement()) {
 6         std::string str;
 7         for (auto attr = e->FirstAttribute(); attr; attr = attr->Next()) {
 8             str += attr->Name();
 9             str += ":";
10             str += attr->Value();
11             str += ",";
12         }
13         log("%s", str.c_str());
14     }

View Code

data.xml

1 <data>
2     <p name="zs" age="23"/>
3     <p name="ls" age="25"/>
4 </data>

上面的代码输出内容为:

cocos2d: name:zs,age:23,
cocos2d: name:ls,age:25,

注:需要导入cosos2d-x库 <tinyxml2/tinyxml2.h>

6、JSON文件读取

先来看一个json  :  [{"name": "zs","age": 23}, {"name": "ls","age": 25}]

1  rapidjson::Document d;
2     d.Parse<0>(fu->getStringFromFile("dj.json").c_str()); // 0表示默认的解析方式;
3     log("%s", d[rapidjson::SizeType(0)]["name"].GetString());

注:需要导入cocos2d-x库  <json/document.h>

cocos2d-x中几种存储数据的方式相关推荐

  1. 除了缓存,浏览器还有哪些存储数据的方式?

    一.简介 浏览器提供3种用于数据存储的 JavaScript APIs:cookie .Web Storage API.IndexedDB. 二.cookie cookie 是最早期 用于存储 键/值 ...

  2. 关于计算机硬盘的详细分类及不同硬盘存储数据的方式

    文章目录 计算机硬盘的发展历史 标志性历史事件 后续发展 现存主要硬盘制造商 计算机硬盘分类 按照运行模式,存储介质和结构分类 按照硬盘接口类型分类 计算机硬盘储存数据的基础知识和原理 机械硬盘 机械 ...

  3. Spring RestTemplate中几种常见的请求方式GET请求 POST请求 PUT请求 DELETE请求

    Spring RestTemplate中几种常见的请求方式 原文地址: https://blog.csdn.net/u012702547/article/details/77917939 版权声明:本 ...

  4. java获取项目中的路径_java中几种获取项目路径方式

    转自http://caodaoxi.iteye.com/blog/1234805 在jsp和class文件中调用的相对路径不同. 在jsp里,根目录是WebRoot 在class文件中,根目录是Web ...

  5. zynq学习03 zynq中三种实现GPIO的方式

    http://m.blog.csdn.net/article/details?id=52123465 http://blog.chinaaet.com/songhuangong/p/43084 本文介 ...

  6. python中导入模块的方式_Python中几种导入模块的方式总结

    模块内部封装了很多实用的功能,有时在模块外部调用就需要将其导入.常见的方式有如下几种: 1 . import >>> import sys >>> sys.path ...

  7. [SpringBoot2]ajax函数中data参数的数据设置方式

    ajax函数中data参数的数据设置方式:

  8. python导入模块有几种_Python中几种导入模块的方式总结

    模块内部封装了很多实用的功能,有时在模块外部调用就需要将其导入.常见的方式有如下几种: 1 . import >>> import sys >>> sys.path ...

  9. Python中三种表示NA的方式

    Python中三种表示NA的方式 # -*- coding: utf-8 -*- import numpy as np import pandas as pd# data_frame = np.loa ...

最新文章

  1. 本周开课——6天精通AI、PS、GraphPad Prism等软件,轻松制作各种高分SCI杂志插图!...
  2. 开发者欣慰:苹果表软件圣诞表现不错
  3. springmvc如何使用视图解析器_SpringMVC工作原理
  4. a33 linux内核启动网卡,a33核心板启动问题 - nevermore1981的个人空间 - OSCHINA - 中文开源技术交流社区...
  5. 输出结果 配置_经典架构新玩法:用单端仪表放大器实现全差分输出
  6. dmb显示服务器断开连接,dmb联网信息发布系统操作手册企业加强版.docx
  7. flex发布的release程序要配release的Flash Player,速度飞快!如果有一方是debug版本的,速度就降下来了,要注意!...
  8. jQuery入门视频教程
  9. 面向对象需求分析方法实践
  10. 如何设置二级标题:当鼠标放到一级标题上二级标题才会显示出来
  11. python3写360图库爬虫
  12. f检验matlab计算,方差分析F检验的步骤和判定
  13. photoshop动作怎么安装?PS怎么导入动作?ps动作安装方法详细教程
  14. Quartus II——基于VGA的图像显示
  15. 短信验证码平台哪家速度快又稳定,推荐下?
  16. android sku 库存管理,建议收藏!为什么合理的SKU设置对有效库存管理与销售至关重要?...
  17. Google 不想与甲骨文争了,要放弃 Java APIs
  18. 选中一次格式刷,即可多次使用WPS格式刷的办法
  19. 机器人旋转关节非线性摩擦辨识
  20. Android (嘤)英语语音识别 简单概况

热门文章

  1. 浏览器无法打开摄像头
  2. 使用adb命令控制Android
  3. 【TypeScript】字符串转义符序列
  4. angular @ViewChild使用
  5. 9.匿名函数:lambda表达式/filter()/map()
  6. 【opencv】13.摄像头焦距和视场角
  7. Vue.js 生产环境部署
  8. Spring实现AOP的4种方式
  9. 菜鸟要做架构师(一)——如何快速开发中小型系统
  10. 使用matlab版卷及神经网络 MatconvNe和预训练的imageNet进行图像检Image retrieval using MatconvNet and pre-trained imageNet