Cocos2d-x文件管理FileUtils
声明:本文分析的是cocos2d-x-3.13的代码
文件管理与平台相关,各个平台都不相同,Cocos中实现了一个类FileUtils,统一文件的查找、读取、写入、删除、修改。
FileUtils相关的类图,大致如下:
FileUtils类为一个接口类,定义了查找、读取、写入、删除等接口。各个平台会有平台具体的实现类,在Windows上为FileUtilsWin32类,位于CCFileUtils-win32.h/ CCFileUtils-win32.cpp文件中。
FileUtils类采用单例模式实现,static FileUtils*FileUtils::getInstance()函数可以获取相应的实例。FileUtils::getInstance函数实现在相应平台的FileUtilsXXX的文件中,这样在实例化FileUtils类时,会根据平台创建相应的类型。
ResizableBuffer是读取时使用的缓存类,该类实现了ResizableBuffer接口。Cocos默认支持三种格式的缓存std::string、std::vecror、cocos2d::Data,如果想要自己实现缓存可以,只需要实现ResizableBuffer接口。
FileUtils文件查找搜索相关的成员函数
//获取文件绝对路径
std::string fullPathForFilename(const std::string&filename) const;
//设置/添加查找目录中的子目录
void setSearchResolutionsOrder(const std::vector<std::string>&searchResolutionsOrder);
void addSearchResolutionsOrder(const std::string&order,const bool front=false);
//设置/添加查找目录
void addSearchPath(const std::string&path,const bool front=false);
void setSearchPaths(const std::vector<std::string> &searchPaths);
//设置/获取文件别名
void setFilenameLookupDictionary(const ValueMap &filenameLookupDict);
std::string fullPathFromRelativeFile(const std::string&filename,
const std::string&relativeFile);
//文件/目录是否存在
bool isFileExist(const std::string &filename) const;
bool isDirectoryExist(const std::string &dirPath)const;
//是否时绝对路径
bool isAbsolutePath(const std::string &path) const;
Cocos中可以设置个文件搜索路径,保存在searchPathArray数组中。每个搜索路径中还可以搜索的子目录,保存在searchResolutionsOrderArray数组中。例如:
searchPathArray:C:/Game/Picture,C:/Game/Text
searchResolutionsOrderArray:1.0,2.0
搜索的路径有
C:/Game/Picture/1.0、C:/Game/Picture/2.0、C:/Game/Text/1.0、C:/Game/Text/2.0
searchPathArray数组在初始化时会设置一个默认路径,资源路径(Win32为.exe的目录)。
searchResolutionsOrderArray数组会设置一个空字符串,所以默认只在资源目录下搜索。
以下是FileUtils的初始化函数:
bool FileUtils::init()
{
_searchPathArray.push_back(_defaultResRootPath);
_searchResolutionsOrderArray.push_back("");
returntrue;
}
fullPathForFilename函数内部会将searchPathArray中每条目录与searchResolutionsOrderArray中字符串组合对文件进行查找,如果查找到文件则会返回,文件的绝对路径,停止继续查找。如果所有路径都没有找到则会返回一个空路径。
setFilenameLookupDictionary函数可以给文件设置别名,如将table.jpeg的别名设为tabe.jpg,则搜索文件时会将table.jpeg改为tabe.jpg搜索文件。
文件缓存
Cocos读取文件时会将整个文件读取到缓存中,默认支持的缓存有三种std::string、std::vecror、cocos2d::Data。
使用std::string作为缓存时,读取完数据后,将会生成一个std::string。
使用std::vecror可以使用任意数据类型为缓存,读取完后存放在相应的数组中。
cocos2d::Data是Cocos中的byte字节组,使用cocos2d::Data作为缓存读取文件,读取完后文件会以二进制的方式存放在cocos2d::Data中。
缓存接口
class ResizableBuffer{
public:
virtual ~ResizableBuffer(){}
virtual void resize(size_tsize)= 0;
virtual void* buffer() const = 0;
};
读取数据时使用的缓存都需要继承至该接口。如果想要实自定义的缓存,只需要实现该接口就行。
默认缓存
三个默认的缓存都采用ResizableBufferAdapter模板实现
string类型缓存
template<typename CharT,typename Traits,typename Allocator>
class ResizableBufferAdapter<std::basic_string<CharT,Traits,Allocator>> : public ResizableBuffer
sting的定义typedef basic_string<char,char_traits<char>,allocator<char>> string;
vecror类型缓存
template<typenameT,typename Allocator>
class ResizableBufferAdapter<std::vector<T,Allocator>> : public ResizableBuffer
Data类型缓存
template<>
class ResizableBufferAdapter<Data>:public ResizableBuffer
读取文件
FileUtils提供了以下成员函数读取数据:
//读取文件并存放到string中,使用string类型缓存
std::string getStringFromFile(const std::string& filename)
//读取数据返回一个Data,使用Data类型缓存
Data getDataFromFile(const std::string& filename)
//读取数据到缓存
Status getContents(const std::string& filename,ResizableBuffer* buffer)
Status getContents(const std::string& filename,T* buffer)
写入数据
因为各个平台对文件写入可能会有目录权限的限制,所以Cocos为了实现统一接口写入数据,提供了以下函数:
std::string getWritablePath() const = 0;//获取写入路径
void setWritablePath(const std::string&writablePath);//设置写入路径
//写入string
bool writeStringToFile(const std::string &dataStr,const std::string &fullPath);
//写入Data
bool writeDataToFile(const Data &data,const std::string &fullPath);
FileUtils还支持ValueMap格式的XML文件的读取,可以直接读取XML文件,返回ValueMap对象。并且支持将ValueMap对象直接以XML文件的方式写入文件。这一部分会在ValueMap章节介绍。