cocos2dx 文件操作
在游戏开发中,通常不需要复杂的文件读写操作,但一些基本的 Cocos2d-x 文件操作仍有必要了解。本文将详细介绍 Cocos2d-x 中 FileUtils 类的文件操作功能。
FileUtils 类概述
FileUtils 类的主要功能是设置加载和保存文件的所在路径。该类是一个单例类,可以通过 getInstance() 方法获取单例对象。以下是相关方法:
// 获得单例对象
static FileUtils* getInstance();
// 释放单例对象资源
static void destroyInstance();
// 清理文件查找缓存
virtual void purgeCachedEntries();
文件操作功能详解
1. 文件读取
FileUtils 类提供了多种读取文件的方法:
// 读取文件内容,返回 Data 类型的数据
virtual Data getDataFromFile(const std::string& filename);
// 读取文件内容,返回字符串类型的数据
virtual std::string getStringFromFile(const std::string& filename);
// 读取 zip 中某资源文件的内容
// [in] zip 文件路径 , 相对 zip 的文件路径
// [out] size. 若文件读取成功,这个值为数据大小,否则为零
// 如果成功,则返回数据指针,否则返回 nullptr
virtual unsigned char* getFileDataFromZip(const std::string& zipFilePath, const std::string& filename, ssize_t *size);
2. 文件查找
2.1 设置文件查找路径
- 文件字典(Dictionary):相当于给文件起别名。
- 搜索路径(SearchPaths):可以是绝对路径或相对路径。
- 子区分路径(SearchResolutionsOrder):用于进一步细分查找路径。
相关方法如下:
// 设置文件词典,相当于给文件起别名,如 map["sprite.png"] = "sp.png"
virtual void setFilenameLookupDictionary(const ValueMap& filenameLookupDict);
// 从 plist 文件加载文件词典
virtual void loadFilenameLookupDictionaryFromFile(const std::string &filename);
// 设置搜索路径(可以是绝对路径、相对路径),清除之前 add 的全部搜索路径(除了默认路径 "Resources")
virtual void setSearchPaths(const std::vector<std::string>& searchPaths);
// 添加搜索路径
void addSearchPath(const std::string & path, const bool front=false);
// 获取搜索路径
virtual const std::vector<std::string>& getSearchPaths() const;
// 设置子区分路径,清除之前 add 的全部子区分路径
virtual void setSearchResolutionsOrder(const std::vector<std::string>& searchResolutionsOrder);
// 添加子区分路径
virtual void addSearchResolutionsOrder(const std::string &order,const bool front=false);
// 获取子区分路径
virtual const std::vector<std::string>& getSearchResolutionsOrder();
2.2 查找文件
fullPathForFilename:获取文件的完整路径(绝对路径),注意查找的是文件,而不是文件夹。fullPathFromRelativeFile:路径拼接。
// 获取文件的完整路径(绝对路径)
virtual std::string fullPathForFilename(const std::string &filename);
// 路径拼接,relativeFile.substr(0, relativeFile.rfind('/')+1) + getNewFilename(filename)
virtual std::string fullPathFromRelativeFile(const std::string &filename, const std::string &relativeFile);
fullPathFromRelativeFile 的用法说明:
- 保留
relativeFile最后一个'/'前面的路径(如:"xyz/123")。 - 通过文件字典替换
filename(如:"sprite.png"->"sp.png")。 - 路径拼接:
"xyz/sp.png"。 - 若
relativeFile = "xyz/123/",则路径拼接为:"xyz/123/sp.png"。
2.3 举例
// 设置文件字典
std::map<std::string, std::string> map;
map["sprite.png"] = "bg.png";
setFilenameLookupDictionary(map);
// 设置搜索路径
std::vector<std::string> searchPaths = {"C:/Res/xyz", "xyz"};
setSearchPaths(searchPaths);
// 设置子区分路径
std::vector<std::string> resolutionsOrder = {"1", "2"};
setSearchResolutionsOrder(resolutionsOrder);
// 获取完整路径
std::string fullPath = fullPathForFilename("sprite.png");
查找过程如下:
- 先根据字典替换别名
"sprite.png"-->"bg.png"。 - 然后查找
"bg.png"(若无字典,直接查找"sprite.png")。 - 按以下顺序查找,并返回
"sprite.png"的完整路径(如"C:/Res/xyz/bg.png"):C:/Res/xyz/1/bg.pngC:/Res/xyz/2/bg.pngC:/Res/xyz/bg.pngC:/projects/MyGame/Resources/xyz/1/bg.pngC:/projects/MyGame/Resources/xyz/2/bg.pngC:/projects/MyGame/Resources/xyz/bg.pngC:/projects/MyGame/Resources/1/bg.pngC:/projects/MyGame/Resources/2/bg.pngC:/projects/MyGame/Resources/bg.png
- 若未找到,返回
"sprite.png"。
注意:若找不到 "bg.png",即使 "C:/Res/xyz/" 路径下存在 "sprite.png",也显示找不到。
3. 文件判断
// 检查文件是否存在(相对路径、绝对路径都可以)
virtual bool isFileExist(const std::string& filename) const;
// 检查路径是不是绝对路径,在 Android 平台上,若 path 是相对于 "assets/",该方法会把它当成绝对路径 true
virtual bool isAbsolutePath(const std::string& path) const;
// 设置图片加载失败时,是否弹出消息框
virtual void setPopupNotify(bool notify);
virtual bool isPopupNotify();
4. 文件写入
4.1 获取写入路径
写入路径一般无法修改,不同平台的文件写入路径不同:
// 获取写入路径
virtual std::string getWritablePath() const = 0;
- Win32:在 exe 文件所在的目录(如
"proj.win32/Debug.win32/")。 - Android:
"/data/data"目录。 - iOS:
"document folder"目录。
4.2 写入文件的方法
可以通过以下两个类来保存游戏的数据:
UserDefault:用于保存游戏中的用户数据。RenderTexture:用于保存游戏中创建的图片数据。
具体操作,请学习 UserDefault、RenderTexture 两个类。
5. 文件查找的应用(精灵的创建)
精灵的创建需要一张图片资源,创建过程中会调用 fullPathForFilename("sprite.png") 来查找图片所在路径,然后根据图片创建精灵。
如果不设置文件查找的路径,Win32 项目默认会在 "Resources" 中查找图片,而 Android 项目默认会在 "assets" 中查找资源图片。
以下是通过前面例子的分析:
// 设置文件字典
std::map<std::string, std::string> map;
map["sprite.png"] = "bg.png";
setFilenameLookupDictionary(map);
// 设置搜索路径
std::vector<std::string> searchPaths = {"C:/Res/xyz", "xyz"};
setSearchPaths(searchPaths);
// 设置子区分路径
std::vector<std::string> resolutionsOrder = {"1", "2"};
setSearchResolutionsOrder(resolutionsOrder);
// 创建精灵
Sprite* sp = Sprite::create("sprite.png");
查找过程如下:
- 调用
fullPathForFilename("sprite.png"),查找图片所在路径。 - 先根据字典替换别名
"sprite.png"-->"bg.png"。 - 然后查找
"bg.png"(若无字典,直接查找"sprite.png")。 - 按以下顺序查找,并返回
"sprite.png"的完整路径(如"C:/Res/xyz/bg.png"):C:/Res/xyz/1/bg.pngC:/Res/xyz/2/bg.pngC:/Res/xyz/bg.pngC:/projects/MyGame/Resources/xyz/1/bg.pngC:/projects/MyGame/Resources/xyz/2/bg.pngC:/projects/MyGame/Resources/xyz/bg.pngC:/projects/MyGame/Resources/1/bg.pngC:/projects/MyGame/Resources/2/bg.pngC:/projects/MyGame/Resources/bg.png
- 若未找到
"bg.png",继续查找"sprite.png"。 - 若依旧未找到
"sprite.png",则报错。 - 若找到图片所在路径,则用该图片创建精灵。
注意:如果 "C:/Res/xyz/" 路径同时存在 "bg.png" 和 "sprite.png",那么创建的精灵所使用的资源图片为 "bg.png",而不是 "sprite.png"。