cocos2dx 文本处理
在 Cocos2dx 开发中,文本处理有一些需要注意的地方,下面我们来详细探讨相关问题。
问题 1:fopen 在不同平台的兼容性问题
在 Visual Studio(VS)环境下使用 fopen 进行文件处理时,程序可以正常运行,但将项目移植到 Android 平台后,却出现了一系列问题。这是因为在 VS 环境下开发时,资源通常存放在执行文件的相同目录下;而移植到 Android 平台后,资源存放在 assets 目录下。
以下是之前尝试使用的代码:
char* fileName = "bg.png";
string filepath = CCFileUtils::sharedFileUtils()->fullPathForFilename(fileName);
FILE *fp = fopen(filepath.c_str(), "r");
然而,使用上述代码会导致程序报错,游戏一启动就崩溃。推测这与底层实现有关,但未进行深入探究。解决此问题的方法是使用 Cocos2dx 的 CCFileUtils,示例代码如下:
char* filename = "bg.png";
// 获得文件在系统的绝对路径 -- assets/bg.png
string filepath = CCFileUtils::sharedFileUtils()->fullPathForFilename(filename);
// 读取的字节数,读取失败则为 0
unsigned long len = 0;
// 读取的内容
unsigned char *data = CCFileUtils::sharedFileUtils()->getFileData(filepath.c_str(), "rb", &len);
/*
此处进行你对文件的操作
*/
// 最后记得释放内存
if(len > 0 && data) delete[] data;
getFileData 接口说明
static unsigned char* getFileData ( const char * pszFileName,
const char * pszMode,
unsigned long * pSize
)
pszMode 参数的详细说明:
r:以只读方式打开文件,该文件必须存在。r+:以可读写方式打开文件,该文件必须存在。rb+:读写打开一个二进制文件,允许读数据。rt+:读写打开一个文本文件,允许读和写。w:打开只写文件,若文件存在则文件长度清为 0,即该文件内容会消失。若文件不存在则建立该文件。w+:打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。a:以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留(EOF 符保留)。a+:以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留(原来的 EOF 符不保留)。wb:只写打开或新建一个二进制文件;只允许写数据。wb+:读写打开或建立一个二进制文件,允许读和写。wt+:读写打开或着建立一个文本文件;允许读写。at+:读写打开一个文本文件,允许读或在文本末追加数据。ab+:读写打开一个二进制文件,允许读或在文件末追加数据。
问题 2:TinyXML 在不同平台的兼容性问题
在使用 TinyXML 读取 XML 文件时,之前的做法如下:
// 根据 xml 数据创建动画
string xmlFile_path = "bg.xml";
// 读取动作 XML 文件
tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
doc->LoadFile(xmlFile_path.c_str());
tinyxml2::XMLElement *ani_node = doc->RootElement();
tinyxml2::XMLElement *action_node = ani_node->FirstChildElement("action");
上述代码在 VS 环境下可以正常运行,但移植到 Android 平台后程序崩溃。解决办法是先将 XML 文件读取到一个缓冲区,然后让 TinyXML 解析这个缓冲区,从而绕过读取文件失败的问题。示例代码如下:
// 根据 xml 数据创建动画
string xmlFile_path = "bg.xml";
// 获得文件在系统的绝对路径
string xmlfilepath = CCFileUtils::sharedFileUtils()->fullPathForFilename(xmlFile_path.c_str());
// 读取的字节数,读取失败则为 0
unsigned long len = 0;
// 读取的内容
unsigned char *data = CCFileUtils::sharedFileUtils()->getFileData(xmlfilepath.c_str(), "r", &len);
// 读取动作 XML 文件
tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
doc->Parse((char*)data, len);
tinyxml2::XMLElement *ani_node = doc->RootElement();
tinyxml2::XMLElement *action_node = ani_node->FirstChildElement("action");
通过以上方法,可以解决 Cocos2dx 中 fopen 和 TinyXML 在不同平台上的兼容性问题,确保程序在不同平台上都能稳定运行。