文件系統(tǒng)的功能:
1.資源包裹
2.提供資源載入速度
3.資源加密
在蓋莫游戲引擎中
文件系統(tǒng)由讀文件,寫文件,XML序列化對象,ConfigFile構(gòu)成
文件系統(tǒng)的接口如下:
1.讀文件
////////////////////////////////////////////////////////////
/// 定義讀2進制文件抽象基類
////////////////////////////////////////////////////////////
class GAPI ReadFile: public Object
{
public:
////////////////////////////////////////////////////////
/// 讀文件構(gòu)造函數(shù),析構(gòu)函數(shù)
////////////////////////////////////////////////////////
ReadFile();
virtual ~ReadFile();
////////////////////////////////////////////////////////
///讀取文件數(shù)據(jù)
////////////////////////////////////////////////////////
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;
////////////////////////////////////////////////////////
///獲取當(dāng)前游標(biāo)位置
////////////////////////////////////////////////////////
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:
////////////////////////////////////////////////////////
/// 寫文件構(gòu)造函數(shù),析構(gòu)函數(shù)
////////////////////////////////////////////////////////
WriteFile();
virtual ~WriteFile();
////////////////////////////////////////////////////////
///寫數(shù)據(jù)
////////////////////////////////////////////////////////
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;
////////////////////////////////////////////////////////
///獲取當(dāng)前游標(biāo)位置
////////////////////////////////////////////////////////
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:
////////////////////////////////////////////////////////
/// 構(gòu)造函數(shù)和析構(gòu)函數(shù)
////////////////////////////////////////////////////////
ConfigFile();
ConfigFile(const std::string& filename);
~ConfigFile();
public:
////////////////////////////////////////////////////////
/// 打開指定文件
////////////////////////////////////////////////////////
bool Open(const std::string& filename);
////////////////////////////////////////////////////////
/// 把配置文件數(shù)據(jù)寫入磁盤
////////////////////////////////////////////////////////
void Flush();
////////////////////////////////////////////////////////
/// 關(guān)閉配置文件
////////////////////////////////////////////////////////
void Close();
////////////////////////////////////////////////////////
/// 寫(讀)數(shù)據(jù)的函數(shù)(不可使用于UDT數(shù)據(jù))
////////////////////////////////////////////////////////
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;
//! 寫數(shù)據(jù)到字符串
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) );
//! 寫數(shù)據(jù)
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
////////////////////////////////////////////////////////
/// 定義引擎文件系統(tǒng)
////////////////////////////////////////////////////////
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);
////////////////////////////////////////////////////
/// 獲取文件系統(tǒng)注冊資源包列表
////////////////////////////////////////////////////
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;
////////////////////////////////////////////////////////
///文件的創(chuàng)建
////////////////////////////////////////////////////////
RefPtr<WriteFile> GetWrite(const engine_string& filename);
////////////////////////////////////////////////////////
///文件的打開
////////////////////////////////////////////////////////
RefPtr<ReadFile> GetRead(const engine_string& filename);
private:
FileSystemImpl *impl;
DEFINE_SINGLETON(FileSystem);
};
可以看出文件系統(tǒng)提供的功能有
獲取用戶目錄
獲取當(dāng)前程序目錄
設(shè)置資源包
獲取給定目錄下文件列表(資源包文件,硬盤文件)
以及打開給定文件等
簡單的測試?yán)尤缦?
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.