cocos2d-x中几种存储数据的方式

来源:互联网 发布:淘宝开店阿里巴巴进货 编辑:程序博客网 时间:2024/06/07 14:40
1.CCUserDefault.
转自:http://blog.sina.com.cn/s/blog_82ca0a770101106d.html


  • 先介绍CCUserDefault类

此类采用单例模式,可以通过sharedUserDefault()函数获取其唯一实例

CCUserDefault采用XML存储技术,就是一般的键值对,初学者也能容易的掌握

访问方式为CCUserDefault::sharedUserDefault()

这句话比较长,而且用的地方也比较多,所以建议采用宏定义简化代码

如下: #define userDefaultCCUserDefault::sharedUserDefault()

其实现的接口也比较简单实用,通过传统的get()、set()方法访问和修改值

如下:

 

//获取bool型值
 bool getBoolForKey(const char*pKey, bool defaultValue = false);
 //获取整型值
 int  getIntegerForKey(constchar* pKey, int defaultValue = 0);
//获取浮点数值
 float getFloatForKey(const char*pKey, float defaultValue=0.0f);
 //获取双精度浮点数值
 double  getDoubleForKey(constchar* pKey, double defaultValue=0.0);
//获取字符串
 std::string getStringForKey(const char* pKey,const std::string & defaultValue = "");

 

 

//设置布尔型值

void setBoolForKey(const char*pKey, bool value);
 //设置整型值
 void setIntegerForKey(constchar* pKey, int value);
 //设置浮点数值
 void setFloatForKey(const char*pKey, float value);
 //双精度浮点数值
 void setDoubleForKey(const char*pKey, double value);
 //设置字符串值
 void setStringForKey(const char*pKey, const std::string & value);

  • 接下来是其一般存储与初始化流程

该存储文件名已经规定了为UserDefault.xml,当该文件不存在是会自动创建,存在之后直接存取就行了,不需要过多的操作

通过以下代码,以判断该文件是否存在,不存在就创建并写入记录,表明其已经存在。

当然这显得有些多余,因为直接写一条记录也会使其创建并且不会破坏其数据。

但对于程序员来说,这是一个好习惯

 if(!userDefault->getBoolForKey("isExisted")){
  userDefault->setBoolForKey("isExisted",true);//不知道userDefault是啥?正文第五行,自己翻去
 }

这样数据存储就初始化好了,之后直接调用get、set等方法就可以直接存取数据了

 

参考文档:http://4137613.blog.51cto.com/4127613/770754





2.CCFileUtils

转自:

http://blog.csdn.net/chiuan/article/details/8618411

为了保存自定义数据文件,需要保存文件和读取文件,也就是File的IO处理;

针对cocos2d-x我们可以通过CCFileUtils::sharedFileUtils()->getWriteablePath()获取到可读写的文件目录,其实是Caches目录。


关于file的操作,我们要明白几个概念:

File :文件对象,用于创建文件,操作文件

fopen:打开操作一个具体文件(文件路径,模式)模式有"w"\"r"读写等

fseek:移动文件指针

ftell:得到文件指针的位置,距离开头

rewind:文件指针重置

malloc:分配内存空间

fread:读一个文件的内容,需要输入buf储存空间,单位大小,长度,文件指针

fputs:写内容进去一个文件


摘录读取模式

    r 以只读方式打开文件,该文件必须存在。   
    r+ 以可读写方式打开文件,该文件必须存在。   
    rb+ 读写打开一个二进制文件,允许读数据。   
    rt+ 读写打开一个文本文件,允许读和写。   
    w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。   
    w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。   
    a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保    留。(EOF符保留)   
    a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)   
    wb 只写打开或新建一个二进制文件;只允许写数据。   
    wb+ 读写打开或建立一个二进制文件,允许读和写。   
    wt+ 读写打开或着建立一个文本文件;允许读写。   
    at+ 读写打开一个文本文件,允许读或在文本末追加数据。   
    ab+ 读写打开一个二进制文件,允许读或在文件末追加数据。


以下是代码,2个静态方法,保存和读取:TDInvFileUtils.h

[cpp] view plaincopyprint?
  1. //  
  2. //  TDInvFileUtils.h  
  3. //  MyCocoa2DTest  
  4. //  
  5. //  Created by 韦 柱全 on 13-2-27.  
  6. //  
  7. //  
  8.   
  9. #ifndef __MyCocoa2DTest__TDInvFileUtils__  
  10. #define __MyCocoa2DTest__TDInvFileUtils__  
  11.   
  12. #include <iostream>  
  13. #include "cocos2d.h"  
  14. using namespace cocos2d;  
  15. using namespace std;  
  16.   
  17. /** 负责操作文件储存和读取 
  18.  */  
  19.   
  20. class TDInvFileUtils {  
  21. public:  
  22.     /** 读取本地文件,返回数据 */  
  23.     static string getFileByName(string pFileName);  
  24.       
  25.     /** 储存内容到文件 */  
  26.     static bool saveFile(char* pContent,string pFileName);  
  27.       
  28. };  
  29.   
  30. #endif /* defined(__MyCocoa2DTest__TDInvFileUtils__) */  

其实现文件 TDInvFileUtils.cpp
[cpp] view plaincopyprint?
  1. //  
  2. //  TDInvFileUtils.cpp  
  3. //  MyCocoa2DTest  
  4. //  
  5. //  Created by 韦 柱全 on 13-2-27.  
  6. //  
  7. //  
  8.   
  9. #include "TDInvFileUtils.h"  
  10.   
  11. string TDInvFileUtils::getFileByName(string pFileName){  
  12.     //第一先获取文件的路径  
  13.     string path = CCFileUtils::sharedFileUtils()->getWriteablePath() + pFileName;  
  14.     CCLOG("path = %s",path.c_str());  
  15.       
  16.     //创建一个文件指针  
  17.     FILE* file = fopen(path.c_str(), "r");  
  18.       
  19.     if (file) {  
  20.         char* buf;  //要获取的字符串  
  21.         int len;    //获取的长度  
  22.         /*获取长度*/  
  23.         fseek(file, 0, SEEK_END);   //移到尾部  
  24.         len = ftell(file);          //提取长度  
  25.         rewind(file);               //回归原位  
  26.         CCLOG("count the file content len = %d",len);  
  27.         //分配buf空间  
  28.         buf = (char*)malloc(sizeof(char) * len + 1);  
  29.         if (!buf) {  
  30.             CCLOG("malloc space is not enough.");  
  31.             return NULL;  
  32.         }  
  33.           
  34.         //读取文件  
  35.         //读取进的buf,单位大小,长度,文件指针  
  36.         int rLen = fread(buf, sizeof(char), len, file);  
  37.         buf[rLen] = '\0';  
  38.         CCLOG("has read Length = %d",rLen);  
  39.         CCLOG("has read content = %s",buf);  
  40.           
  41.         string result = buf;  
  42.         fclose(file);  
  43.         free(buf);  
  44.         return result;  
  45.     }  
  46.     else  
  47.         CCLOG("open file error.");  
  48.       
  49.     return NULL;  
  50. }  
  51.   
  52. bool TDInvFileUtils::saveFile(char *pContent, string pFileName){  
  53.     //第一获取储存的文件路径  
  54.     string path = CCFileUtils::sharedFileUtils()->getWriteablePath() + pFileName;  
  55.     CCLOG("wanna save file path = %s",path.c_str());  
  56.       
  57.     //创建一个文件指针  
  58.     //路径、模式  
  59.     FILE* file = fopen(path.c_str(), "w");  
  60.     if (file) {  
  61.         fputs(pContent, file);  
  62.         fclose(file);  
  63.     }  
  64.     else  
  65.         CCLOG("save file error.");  
  66.       
  67.     return false;  


3.SQLite

转自:

http://4137613.blog.51cto.com/4127613/772518

 cocos2d-x学习笔记17:记录存储2:SQLite基本使用


一、安装与配置
SQLite是使用非常广泛的嵌入式数据库,它有着0配置,占用资源少等特点。从大型游戏《魔兽世界》到android上的很多游戏和软件(google提供了一个java语言的绑定。)

在cocos2d-x中,我们使用它的C语言绑定。
为了方便和简化篇幅,我们直接使用它的源代码。下载地址:
http://www.sqlite.org/sqlite-amalgamation-3071000.zip 
 
将其解压到cocos2d-x引擎目录下,得到一个“sqlite-amalgamation-3071000”文件夹,里面有四个源文件。

在VC中新建一个项目,起名叫Save。

然后,右键点项目-》属性-》配置属性-》C++-》常规-》附加包含目录
添加刚才的解压的源代码路径。
 
下一步,右键点项目-》添加-》现有项,选择那四个源代码文件。然后SQLite就配置好了。

二、初步使用

在HelloworldScene中,添加

  1. #include "sqlite3.h" 
然后在init函数中编写代码

  1. sqlite3 *pDB = NULL;//数据库指针 
  2. char * errMsg = NULL;//错误信息 
  3. std::string sqlstr;//SQL指令 
  4. int result;//sqlite3_exec返回值 
  5.  
  6. //打开一个数据库,如果该数据库不存在,则创建一个数据库文件 
  7. result = sqlite3_open("save.db", &pDB); 
  8. if( result != SQLITE_OK ) 
  9.       CCLog( "打开数据库失败,错误码:%d ,错误原因:%s\n" , result, errMsg ); 
  10.   
  11.  //创建表,设置ID为主键,且自动增加 
  12. result=sqlite3_exec( pDB, "create table MyTable_1( ID integer primary key autoincrement, name nvarchar(32) ) " , NULL, NULL, &errMsg ); 
  13. if( result != SQLITE_OK ) 
  14.       CCLog( "创建表失败,错误码:%d ,错误原因:%s\n" , result, errMsg ); 
  15.  
  16. //插入数据 
  17. sqlstr=" insert into MyTable_1( name ) values ( '克塞' ) "
  18. result = sqlite3_exec( pDB, sqlstr.c_str() , NULL, NULL, &errMsg ); 
  19. if(result != SQLITE_OK ) 
  20.       CCLog( "插入记录失败,错误码:%d ,错误原因:%s\n" , result, errMsg ); 
  21.  
  22. //插入数据 
  23. sqlstr=" insert into MyTable_1( name ) values ( '葫芦娃' ) "
  24. result = sqlite3_exec( pDB, sqlstr.c_str() , NULL, NULL, &errMsg ); 
  25. if(result != SQLITE_OK ) 
  26.       CCLog( "插入记录失败,错误码:%d ,错误原因:%s\n" , result, errMsg ); 
  27.  
  28. //插入数据 
  29. sqlstr=" insert into MyTable_1( name ) values ( '擎天柱' ) "
  30. result = sqlite3_exec( pDB, sqlstr.c_str() , NULL, NULL, &errMsg ); 
  31. if(result != SQLITE_OK ) 
  32.       CCLog( "插入记录失败,错误码:%d ,错误原因:%s\n" , result, errMsg ); 
  33.  
  34.  //关闭数据库 
  35. sqlite3_close(pDB); 


然后执行项目,你看不到什么东西,因为只是操作了数据库。

三、SQLite数据库管理工具

SQLite Database Browser是一个用Qt编写的跨平台SQLite数据库管理工具。这个工具的特点是非常简单易用, 甚至很多人拿这个修改SQLite游戏存档。(哈哈哈,关于SQLite加密问题,我们以后会讲。)
这里附上他的下载地址:
http://sourceforge.net/projects/sqlitebrowser/files/latest/download?source=files

然后,我们用这个工具,打开项目目录中Resources目录下的save.db,就可以看到刚才生成的数据库数据了。
 
一共三个标签页,DataBase Structure、Browse Data,Execute SQL……意思一目了然,不用多说。是不是很好用啊,哈哈哈。


四、其他常见SQLite操作举例

还是以上面的表举例,直接给出操作代码。具体接口解释可以参考官方文档:http://www.sqlite.org/docs.html
为了突出主要内容,删掉了一些调试信息。

1)更新记录
把第三条改成威震天 
  1. sqlstr="update MyTable_1 set name='威震天' where ID = 3"
  2.  sqlite3_exec( pDB, sqlstr.c_str() , NULL, NULL, &errMsg ); 

2)删除记录
把第二条葫芦娃删了 
  1. sqlstr="delete from MyTable_1 where ID = 2"
  2.  sqlite3_exec( pDB, sqlstr.c_str() , NULL, NULL, &errMsg ); 

3)判断表是否存在
判断表MyTable_1是否存在,保存在isExisted_中。
  1. bool isExisted_; 
  2. sqlstr="select count(type) from sqlite_master where type='table' and name='MyTable_1'"
  3. sqlite3_exec( pDB, sqlstr.c_str() , isExisted, &isExisted_, &errMsg ); 

这里用到了一个回调函数isExisted,他的定义如下
  1. int isExisted( void * para, int n_column, char ** column_value, char ** column_name ) 
  2.             bool *isExisted_=(bool*)para; 
  3.             *isExisted_=(**column_value)!='0'
  4.             return 0; 

4)判断记录是否存在
判断ID=2的记录是否存在,保存在isExisted_中。
  1.  bool isExisted_; 
  2. sqlstr="select count(*) from MyTable_1 where ID = 2"
  3. sqlite3_exec( pDB, sqlstr.c_str() , isExisted, &isExisted_, &errMsg ); 
回调函数isExisted的定义,在3)已给出,不再赘述。

5)获得记录条数
获得表MyTable_1的记录条数,保存在count中。 
  1. int count; 
  2.  sqlstr="select * from MyTable_1"
  3.  sqlite3_exec( pDB, sqlstr.c_str() , loadRecordCount, &count, &errMsg ); 

这里用到了一个回调函数loadRecordCount,他的定义如下
  1. int loadRecordCount( void * para, int n_column, char ** column_value, char ** column_name ) 
  2.             int *count=(int*)para; 
  3.             *count=n_column; 
  4.             return 0; 
 
6)读取一条记录
读取表MyTable_1中ID=3的记录,并打印
  1. sqlstr="select * from MyTable_1 where ID=3"
  2. sqlite3_exec( pDB, sqlstr.c_str() , loadRecord, NULL, &errMsg ); 

这里用到了一个回调函数loadRecord,他的定义如下
  1. int loadRecord( void * para, int n_column, char ** column_value, char ** column_name ) 
  2.             CCLog("ID=%s,name=%s",column_value[0],column_value[1]); 
  3.             return 0; 

本文出自 “老G的小屋” 博客,请务必保留此出处http://4137613.blog.51cto.com/4127613/772518


原创粉丝点击