文件系统的功能:
1.资源包裹
2.提供资源载入速度
3.资源加密
在盖莫游戏引擎中
文件系统由读文件,写文件,XML序列化对象,ConfigFile构成
文件系统的接口如下:
1.读文件
////////////////////////////////////////////////////////////
/// 定义读2进制文件抽象基类
////////////////////////////////////////////////////////////
class GAPI ReadFile: public Object
{
public:
////////////////////////////////////////////////////////
/// 读文件构造函数,析构函数
////////////////////////////////////////////////////////
ReadFile();
virtual ~ReadFile();
////////////////////////////////////////////////////////
///读取文件数据
////////////////////////////////////////////////////////
virtual uint Read(void* buf,uint size,uint number = 1) =0;
////////////////////////////////////////////////////////
///获取文件长度
////////////////////////////////////////////////////////
virtual uint64 GetSize()const=0;
////////////////////////////////////////////////////////
///文件定位
////////////////////////////////////////////////////////
virtual bool Seek(long offset,FILE_SEEK_MODE mode = FILE_SEEK_MODE_CURRENT) = 0;
////////////////////////////////////////////////////////
///获取当前游标位置
////////////////////////////////////////////////////////
virtual uint64 Tell()const = 0;
////////////////////////////////////////////////////////
/// 获取文件名
////////////////////////////////////////////////////////
virtual engine_string GetFileName()const = 0;
////////////////////////////////////////////////////////
///合法性检查
////////////////////////////////////////////////////////
virtual bool IsValid()const = 0;
private:
DECLARE_OBJECT(ReadFile)
};
2.WriteFile
////////////////////////////////////////////////////////////
/// 定义读2进制文件抽象基类
////////////////////////////////////////////////////////////
class GAPI WriteFile : public Object
{
public:
////////////////////////////////////////////////////////
/// 写文件构造函数,析构函数
////////////////////////////////////////////////////////
WriteFile();
virtual ~WriteFile();
////////////////////////////////////////////////////////
///写数据
////////////////////////////////////////////////////////
virtual uint Write(const void* buf,uint size,uint number = 1) = 0;
////////////////////////////////////////////////////////
///文件定位
////////////////////////////////////////////////////////
virtual bool Seek(long position,FILE_SEEK_MODE mode = FILE_SEEK_MODE_CURRENT) = 0;
////////////////////////////////////////////////////////
///获取当前游标位置
////////////////////////////////////////////////////////
virtual uint64 Tell()const = 0;
////////////////////////////////////////////////////////
/// 获取文件名
////////////////////////////////////////////////////////
virtual engine_string GetFileName()const = 0;
////////////////////////////////////////////////////////
///合法性检查
////////////////////////////////////////////////////////
virtual bool IsValid()const = 0;
private:
DECLARE_OBJECT(WriteFile)
};
3.ConfigFile.
////////////////////////////////////////////////////////////
/// 定义解析ini文件对象
////////////////////////////////////////////////////////////
class GAPI ConfigFile
{
public:
////////////////////////////////////////////////////////
/// 定义搜索的前置条件
////////////////////////////////////////////////////////
template<class Pair>
class StrPairEq : public std::binary_function<Pair,std::string,bool>
{
public:
bool operator()(const Pair& lhs,const std::string& rhs)const;
};
typedef std::pair<std::string,std::string> Variable;
typedef std::list< Variable > Section;
typedef std::pair< std::string, Section > NamedSection;
typedef std::list< NamedSection > Layout;
public:
////////////////////////////////////////////////////////
/// 构造函数和析构函数
////////////////////////////////////////////////////////
ConfigFile();
ConfigFile(const std::string& filename);
~ConfigFile();
public:
////////////////////////////////////////////////////////
/// 打开指定文件
////////////////////////////////////////////////////////
bool Open(const std::string& filename);
////////////////////////////////////////////////////////
/// 把配置文件数据写入磁盘
////////////////////////////////////////////////////////
void Flush();
////////////////////////////////////////////////////////
/// 关闭配置文件
////////////////////////////////////////////////////////
void Close();
////////////////////////////////////////////////////////
/// 写(读)数据的函数(不可使用于UDT数据)
////////////////////////////////////////////////////////
template<class VarType>
void SetVariable(const std::string& sec,const std::string& var,VarType value)
{
std::string sec_brac(BracketString(sec));
Layout::iterator sec_iter;
Section::iterator var_iter;
std::ostringstream ss;
//! 写数据到字符串
ss << value;
//! 检索段
sec_iter = std::find_if(layout.begin(),layout.end(),std::bind2nd(StrPairEq<NamedSection>(),sec_brac));
//! 如果段不存在则增加之
if(sec_iter == layout.end())
{
layout.push_back(NamedSection(sec_brac, Section()));
sec_iter = std::find_if(layout.begin(),layout.end(),std::bind2nd(StrPairEq<NamedSection>(),sec_brac));
}
//! 变量检索
var_iter = std::find_if(sec_iter->second.begin(),sec_iter->second.end(),std::bind2nd(StrPairEq<Variable>(), var) );
//! 写数据
if(var_iter == sec_iter->second.end())
{
sec_iter->second.push_back(Variable(var, ss.str()));
}
else
{
var_iter->second = ss.str();
}
}
template<class VarType>
VarType GetVariable(const std::string& sec,const std::string& var,VarType defval)const
{
std::string sec_brac(BracketString(sec));
std::stringstream ss;
VarType ret(defval);
Layout::const_iterator sec_iter;
Section::const_iterator var_iter;
sec_iter = std::find_if(layout.begin(),layout.end(),std::bind2nd(StrPairEq<NamedSection>(),sec_brac));
if(sec_iter != layout.end())
{
var_iter = std::find_if(sec_iter->second.begin(),sec_iter->second.end(),std::bind2nd(StrPairEq<Variable>(),var));
if(var_iter != sec_iter->second.end())
{
ss.str(var_iter->second);
ss >> ret;
}
}
return ret;
}
////////////////////////////////////////////////////////
/// 获取配置文件有多少个块
////////////////////////////////////////////////////////
uint GetSectionNumber(){return layout.size();}
////////////////////////////////////////////////////////
/// 检索是否存在给定块(块,键)
////////////////////////////////////////////////////////
bool HasSectionName(const std::string §ion)
{
Layout::iterator sec_iter;
sec_iter = std::find_if(layout.begin(),layout.end(),std::bind2nd(StrPairEq<NamedSection>(),section));
return (sec_iter != layout.end());
}
bool HasKeyName(const std::string §ion,const std::string &key)
{
if(HasSectionName(section) == false)
return false;
Layout::iterator sec_iter;
sec_iter = std::find_if(layout.begin(),layout.end(),std::bind2nd(StrPairEq<NamedSection>(),section));
Section::iterator var_iter = std::find_if(sec_iter->second.begin(),sec_iter->second.end(),std::bind2nd(StrPairEq<Variable>(),key));
return (var_iter != sec_iter->second.end());
}
private:
static std::string CleanString(const std::string& str);
static std::string BracketString(const std::string& str);
private:
Layout layout;
std::string filename;
};
template<class Pair>
bool ConfigFile::StrPairEq<Pair>::operator()(const Pair& lhs, const std::string& rhs)const
{
return ConfigFile::CleanString(lhs.first) == ConfigFile::CleanString(rhs);
}
4.FIleSYstem's Core
////////////////////////////////////////////////////////
/// 定义引擎文件系统
////////////////////////////////////////////////////////
class GAPI FileSystem
{
public:
////////////////////////////////////////////////////
/// 获取工作目录
////////////////////////////////////////////////////
engine_string GetWorkDir()const;
////////////////////////////////////////////////////
/// 获取用户目录
////////////////////////////////////////////////////
engine_string GetUserDir()const;
public:
////////////////////////////////////////////////////
/// 注册,反注册资源包文件
////////////////////////////////////////////////////
bool RegisterPackage(const engine_string& package);
bool UnRegisterPackage(const engine_string& package);
////////////////////////////////////////////////////
/// 获取文件系统注册资源包列表
////////////////////////////////////////////////////
void GetPackageList(std::vector<engine_string> &packages);
public:
////////////////////////////////////////////////////
/// 检测给定目录是否为文件目录
////////////////////////////////////////////////////
bool IsDirectory(const engine_string& dir);
////////////////////////////////////////////////////
/// 生成新的硬盘目录
////////////////////////////////////////////////////
bool CreateDirectory(const engine_string& dir);
////////////////////////////////////////////////////
/// 删除一个文件或者一个目录(如果是目录必须确保它是空的)
////////////////////////////////////////////////////
bool DeleteFile(const engine_string& file);
////////////////////////////////////////////////////
/// 检测给定文件是否存在
////////////////////////////////////////////////////
bool IsExist(const engine_string &filename);
////////////////////////////////////////////////////
/// 获取给定文件夹下的文件列表(返回1为硬盘文件列表,0为资源包文件列表)
////////////////////////////////////////////////////
short GetFileList(const engine_string& dir,std::vector<engine_string> &filelist);
////////////////////////////////////////////////////
/// 获取给定文件后缀(比如main.cpp返回.cpp)
////////////////////////////////////////////////////
engine_string GetFileExtension(const engine_string &file)const;
////////////////////////////////////////////////////////
///文件的创建
////////////////////////////////////////////////////////
RefPtr<WriteFile> GetWrite(const engine_string& filename);
////////////////////////////////////////////////////////
///文件的打开
////////////////////////////////////////////////////////
RefPtr<ReadFile> GetRead(const engine_string& filename);
private:
FileSystemImpl *impl;
DEFINE_SINGLETON(FileSystem);
};
可以看出文件系统提供的功能有
获取用户目录
获取当前程序目录
设置资源包
获取给定目录下文件列表(资源包文件,硬盘文件)
以及打开给定文件等
简单的测试例子如下:
core::ConfigFile config;
config.Open("gaimosoft.ini");
config.SetVariable<int>(std::string("block"),std::string("size"),1024);
config.SetVariable<double>(std::string("block"),std::string("rand"),0.32);
config.SetVariable<std::string>(std::string("name"),std::string("name"),std::string("gaimosoft"));
double rand = config.GetVariable(std::string("block"),std::string("rand"),-1.0f);
std::string name = config.GetVariable(std::string("name"),std::string("name"),std::string("mysoft"));
std::cout<<name<<std::endl;
name = config.GetVariable(std::string("name"),std::string("address"),std::string("mysoft"));
std::cout<<name<<std::endl;
config.Close();
std::cout<<GLOBAL_FILESYSTEM_PTR->RegisterPackage("font1.zip")<<endl;
core::RefPtr<core::ReadFile> file = GLOBAL_FILESYSTEM_PTR->GetRead("main.o");
if(file)
std::cout<<"file size is:"<<file->GetSize()<<std::endl;
else
std::cout<<"not find file"<<std::endl;
file->Drop();
std::cout<<GLOBAL_FILESYSTEM_PTR->DeleteFile("1.font")<<std::endl;
我一直在努力ing.