follow my heart...
分类: C/C++
2006-06-06 14:55:12
先附个例子:
#i nclude
#i nclude
//#i nclude "../../../include/MD_File.h"
#i nclude "MD_File.h"
void main()
{
CMD_File file;
file.EnableErrMSG(true); // 当发生错误时弹出对话框
char fn[255],pwd[255]={0};
// 读文件实例
cout<<"请输入要读取的epk文件包的文件名:";
cin>>fn;
cout<<"请输入要读取的epk文件包的密码:";
cin>>pwd;
//open原形bool Open(char* FileName,bool bReadOnly=true,bool bPacked=false,char *password=NULL);
if(!file.Open(fn,true,true,pwd))// 打开一个epk包文件
exit(0);
cout<<"文件包打开成功,请输入要读取的包里的文件名:"; MD File (MDEngine文件系统组件) 版本:2.0.1 支持平台:Microsoft Windows system VC++6 简介: MDFile是一款使用方便、易于扩展的文件系统库,其扩展性体现在两个方面: 特点: 使用简单 可扩展,通过edl或者epk方式扩展 支持外部检索(loss file)特性 epk格式安全性高,使用高效加密方案加密,保护数据的安全性 epk格式支持目录存储结构 epk格式支持单包多编码存储方式,能更有效压缩数据 约定、术语: Extendable Package : 可扩展压缩包,在这类压缩包文件中每个文件的编码方式可以不同,从而得到该文件最合适的一种编码方案。 edl : Encoding/Decoding Library 编码/解码库,一个Dll文件。负责编码、解码数据 FileProvider : 一个dll文件,通过它可以使MDFile支持各种文件包格式,如zip,cab,rar等 文件包 : 将多个文件用某种结构组织起来存储成一个文件,这个文件常称为文件包(如.zip文件) 压缩包 : 等价于文件包。 定位 : 在压缩包中,我们通过定位来通知系统我们要操作包中的哪个文件。 函数接口:
cin>>fn;
//locate原形bool Locate(char* PathName,char *password=NULL); // 定位一个文件
if(file.Locate(fn))
{
file.Read();
cout<<"文件"<
else
cout<<"在包里未找到"<
char a;
cin>>a;
}
1.MDFile内部的epk(extendable package)文件格式的压缩编码方案通过edl(encoding/decoding library)插件可以扩展
2.MDFile支持的压缩包文件可扩展。默认的,MDFile只能打开后缀为.epk的文件格式,通过dll插件的扩展,可以支持zip,cab,rar,ace,lzh.....格式,只要有相应的插件库(FileProvider)就可以了。
CMD_File()
初始化一个CMD_File的实例。
CMD_File(char *)
初始化一个CMD_File的实例,同时挂接到一个外部FileProvider。
void | EnableErrMSG(bool) | 允许或者禁止弹出错误信息窗口 |
bool | GetErrCode() | 得到最近一次错误代码 |
void | EnableExt(bool) | 允许或者禁止外部检索 |
void | SetExt(char *) | 设置外部检索路径 |
bool | ConnectProvider(char *) | 联接到外部FileProvider |
void | FreeProvider() | 释放已经联接到的外部FileProvider |
bool | Open(char*,bool,bool,char *) | 打开一个文件 |
void | Close() | 关闭已经打开的文件 |
bool | Locate(char *,char *) | 定位一个文件 |
DWORD | GetLength() | 普通文件:取得当前打开的文件的长度。 文件包: 当前被定位的文件长度。 |
bool | Read(LPBYTE *,DWORD) | 读取当前文件数据到缓冲 |
bool | Write(LPCVOID,DWORD) | 写数据到当前文件中 |
bool | Seek(long,BYTE) | 移动当前文件指针 |
LPBYTE | GetBuffer() | 取得文件数据缓冲 |
DWORD | GetBufferLength() | 取得文件数据缓冲长度 |
bool | WriteBufferToFile(char *) | 将缓冲区数据写入文件 |
void EnableErrMSG(bool bshowerr)
入口参数:bool bshowerror(true|false)
true : 弹出错误警告窗口
false : 不要弹出错误警告窗口
函数返回:无
函数说明:
当你进行一个CMD_File的操作的时候(比如:执行一个ConnectProvider("zipext.dll")),可能产生一个错误(例如zipext.dll不存在),这时MDFile会记录一个错误信息,如果此时EnableErrMSG设置成true,系统就会弹出一个警告窗口,告诉你出错了。如果此时EnableErrMSG是false,系统不会弹出一个警告窗口,这时你可以使用GetErrorCode来检索这个错误代码。
DWORD GetErrCode(void)
入口参数:无
函数返回:错误代码
函数说明:
当你进行一个CMD_File的操作的时候(比如:执行一个ConnectProvider("zipext.dll")),可能产生一个错误(例如zipext.dll不存在),这时MDFile会记录一个错误信息,用这个函数可以得到这个错误代码(8)
void EnableExt(bool bEnable)
入口参数:bool bEnable(true|false)
true : 允许外部检索
false : 禁止外部检索
函数返回:无
函数说明:
当你读取一个文件的时候,如果指定了外部检索为true,那么系统首先会在对应的文件夹中搜索是否存在这个文件,如果不存在才去读取文件包中的文件。如:
CMD_File file;
file.EnableExt(true);
file.Open("test.epk",true,true);
file.Locate("hi.txt");
file.Read();
此时如果存在在test.epk文件一起的一个test文件夹,同时test文件夹下有hi.txt则系统会读取test文件夹下的hi.txt文件。如果不存在hi.txt文件系统才会读取test.epk包里的hi.txt文件
void SetExt(char *path)
入口参数:char *path (基路径)
函数返回:无
函数说明:
外部检索的目录规则是:基目录+文件包主名,如:
CMD_File file;
file.EnableExt(true);
SetExtFilePath("base");
file.Open("test.epk",true,true);
file.Locate("hi.txt");
file.Read();
假设本程序在C:\test\下,则系统首先会搜索C:\test\base\test\hi.txt。不存在就读取test.epk文件包中的hi.txt
bool ConnectProvider(char *ProviderName)
入口参数:char *ProviderName (FileProvider的文件名)
函数返回:连接到指定的FileProvider是否成功
成功 : true
失败 : false
函数说明:
系统本身仅支持epk格式,需要依靠外部的FileProvider来支持额外的压缩包格式,下面的例子是利用ZipExt.dll这个FileProvider来读取的Zip格式的压缩包:
CMD_File file;
file.ConnectProvider("ZipExt.dll");
file.Open("test.zip",true,true);
file.Locate("data.txt");
file.Read();
注意:
CMD_File file;
file.ConnectProvider("ZipExt.dll");
这两段可以写成一段:CMD_File file("ZipExt.dll")
void FreeProvider(void)
入口参数:无
函数返回:无
函数说明:
使用这个函数可以释放使用ConnectProvider后连接的资源
注意:在绝大多数情况下你完全可以不使用这个函数,我们的系统会在合适的时候为你释放相关的资源
bool Open(char* FileName,bool bReadOnly=true,bool bPacked=false,char *password=NULL)
入口参数:
FileName : 你要打开的文件(包)名
bReadOnly : 是否以只读方式打开,只读方式打开的文件不能使用Write方法写入数据
bPacked : 打开的文件是否作为文件包来处理,文件包不能使用Write方法
password : 打开文件包的密码,通常的文件,文件包可能不需要密码,这时设置为NULL即可,或者忽略这个参数。只有支持加密的文件包才需要这个参数
函数返回:是否成功打开了文件
true : 打开成功
false : 打开失败
函数说明:
这个函数用来打开我们需要操作的文件,这时有两种可能普通文件,或者压缩包(文件包)文件
打开一个普通文件:
CMD_File file;
file.Open("test.txt",false); // 相当于file.Open("test.txt",false,false,NULL);
file.Read(); // 读取test.txt的内容到缓冲区
file.Write("12345678\0",9); // 写入字符串“12345678”到文件中
打开一个压缩包文件:
CMD_File file;
file.Open("test.epk",true,true,"test123"); // 用密码"test123"打开一个名为test.epk的
// 压缩包文件,如果没有密码则使用NULL
file.Locate("txt\\test.txt"); // 在压缩包里面定位txt\test.txt文件
file.Read(); // 读取test.txt的内容到缓冲区
void Close()
入口参数:无
函数返回:无
函数说明:
这个函数用来释放我们打开一个文件后该文件占用的资源。
注意:在绝大多数情况下你完全可以不使用这个函数,我们的系统会在合适的时候为你释放相关的资源
bool Locate(char* PathName,char *password=NULL)
入口参数:
PathName : 你要定位的文件(包)名
password : 定位的文件的密码,通常的文件,文件包可能不需要密码,这时设置为NULL即可,或者忽略这个参数。
函数返回:是否成功定位了文件
true : 定位成功
false : 定位失败
函数说明:
这个函数用来在包中定为一个我们需要操作的文件。
注意:本函数只对文件包有效,不支持普通文件。
我们对压缩包的操作都通过使用定位来通知系统我们要操作压缩包里的哪个文件。因此在对压缩包里的文件操作前我们首先要定位文件。
DWORD GetLength()
入口参数:无
函数返回:文件的长度
正常情况下:返回文件的长度(普通文件而言)或者返回当前定位的文件长度(文件包而言)
如果产生错误:返回0xFFFFFFFF(例如文件尚未打开就查询文件长度等)
函数说明:
这个函数用来检索我们已经打开的文件长度或者已经定位的文件长度
如:
CMD_File file;
file.Open("test.txt",false); // 相当于file.Open("test.txt",false,false,NULL);
DWORD len = file.GetLength(); // 得到test.txt文件的长度(字节数)
file.Open("test.epk",true,true);
file.Locate("txt\\test.txt");
len = file.GetLength(); // 得到test.epk中txt\test.txt文件的长度
bool Read(LPBYTE *buffer=NULL,DWORD size=0);
入口参数:
buffer : 接收数据的缓冲地址
buffer为NULL时 : 系统读取内容到系统缓冲区中,随后用户可以使用GetBuffer()来取得这个缓冲区
buffer不为NULL : 如果buffer已分配空间则数据被读取到buffer中,否则buffer将指向系统的缓冲区
size : 要读取的字节数,仅对文件有效,文件包将忽略次参数(随意瞎填一个)
size为0时 : 读取整个文件的长度
size不为0 : 读取size个字节到指定buffer
函数返回:文件是否读取成功
true : 文件读取成功
false : 文件读取失败
函数说明:
将打开的文件或者已经定位的文件读入buffer中。如:
CMD_File file;
file.Open("test.txt",false); // 相当于file.Open("test.txt",false,false,NULL);
BYTE * buf = new BYTE[5]; // 分配缓冲
file.Read(&buf,5); // 读取5个字节到buf中
delete [] buf; // 用完buf后记得释放buf :-)
buf = NULL;
file.Read(&buf); // 相当于file.Read(&buf,0);,执行后buf指向系统的缓冲区
file.Open("test.epk",true,true);
file.Locate("txt\\test.txt");
file.Read(); // 读取文件test\test.txt到系统缓冲中
buf = file.GetBuffer(); // 得到缓冲区地址
bool Write(LPCVOID buffer,DWORD size)
入口参数:
buffer : 要写入文件的数据的缓冲地址
buffer为NULL时 : 系统读取内容到系统缓冲区中,随后用户可以使用GetBuffer()来取得这个缓冲区
buffer不为NULL : 如果buffer已分配空间则数据被读取到buffer中,否则buffer将指向系统的缓冲区
size : 要写入的字节数
函数返回:文件是否读取成功
true : 文件写入成功
false : 文件写入失败
函数说明:
将buffer中的内容写入到当前打开的文件中
注意:不支持写入文件包文件,如果打开文件时设置bReadOnly为true本函数也返回false
例:
CMD_File file;
file.Open("test.txt",false); // 相当于file.Open("test.txt",false,false,NULL);
file.Write("12345678\0",9); // 写入字符串“12345678”到文件中
bool Seek(long move, BYTE method=FILE_CURRENT);
入口参数:
move : 文件指针移动的距离
move < 0 向前移动
move > 0 向后移动
method : 移动的起始位置
FILE_BEGIN : 从文件开头开始开始移动move个字节
FILE_CURRENT : 从文件指针的当前位置移动move个字节
FILE_END : 从文件的结尾移动move个字节
函数返回:移动是否成功
true : 指针移动成功
false : 指针移动失败
函数说明:
移动文件指针。
注意:当打开的是文件时,执行Read,Write都会自动移动文件指针相应的字节数。同时本函数对文件包无效。本函数与WINAPI的seek保持一致
例如:
CMD_File file;
file.Open("test.txt",false); // 相当于file.Open("test.txt",false,false,NULL);
file.Read(NULL,3); // 读取3个字节
file.Seek(0,FILE_BEGIN); // 移动到文件头
file.Read(NULL,4); // 从头开始读取4个字节
LPBYTE GetBuffer()
入口参数:无
函数返回:系统缓冲区地址
函数说明:
MDFile系统中自带了一个数据缓冲来临时存放从文件中读取的数据。以方便用户的使用。用这个函数可以取得缓冲的地址。
DWORD GetBufferLen()
入口参数:无
函数返回:系统缓冲区长度(字节数)
函数说明:
MDFile系统中自带了一个数据缓冲来临时存放从文件中读取的数据。以方便用户的使用。用这个函数可以取得缓冲的长度。
bool WriteBufferToFile(char *PathName)
入口参数:PathName (要写入的文件的路径、文件全名)
函数返回:写入是否成功
true : 写入成功
false : 写入失败
函数说明:
MDFile系统中自带了一个数据缓冲来临时存放从文件中读取的数据。以方便用户的使用。用这个函数可以将缓冲区的内容写到一个指定的文件中。
例如:
CMD_File file;
file.Open("test.epk",true,true);
file.Locate("txt\\test.txt");
file.Read(); // 读取文件test\test.txt到系统缓冲中
file.WriteBufferToFile("output.txt"); // 写到output.txt文件中
EDL(Encoding/Decoding Library)的开发接口:
扩展库后缀 : .edl
必须接口:
注意:在该EDL中一定要有以下函数,请注意大小写 :-)
DWORD getProviderType(void){ return 0x45444650; }
这个函数必须返回0x45444650,以表示这个库是EDL。
DWORD getProviderVersion(void){ return 0xaabbccdd; }
这个函数应该返回该库的版本。0xaabbccdd表示版本170.187.204.221
char* getProviderName()
这个函数应该返回该库的名称。
char* getProviderInfo()
这个函数应该返回该库的说明信息。
void About()
这个函数应该显示该库的关于对话框。注意:你只需要实现getProviderInfo()或者About中的任何一个即可。
DWORD getMemNeeded(DWORD len)
这个函数应该返回编码(压缩)一个len长度的文件所需要的内存块需要多少字节的内存。
bool Encode(LPBYTE *in,DWORD inlen,LPBYTE *out,DWORD &outlen)
编码函数,这个函数负责对字节流的编码工作
in : 需要编码(压缩)的字节流的地址
inlen : 需要编码(压缩)的字节流长度
out : 输出编码后的字节流的目标地址
outlen: 编码后的字节流的长度
bool Decode(LPBYTE *in,DWORD inlen,LPBYTE *out)
解码函数,这个函数负责对字节流的解码工作
in : 需要解码的字节流的地址
inlen : 需要解码的字节流的长度
out : 输出解码后的字节流的地址
outlen: 解码后的字节流的长度
FileProvider的开发
必须接口 :
注意:在该FileProvider中一定要有以下函数,请注意大小写 :-)
DWORD getProviderType(void){return 0x4650454C;}
这个函数必须返回0x4650454C,以表示这个库是FileProvider。
bool setFileHandle(HANDLE h,char *filename,char *passowrd)
这个函数用来指定操作的文件(压缩包)的句柄,文件名以及访问密码。
这个句柄或文件名表示要操作的文件对象。
bool Locate(char *pathname,char *password)
这个函数用于定位包中的文件,以便接下来的操作。定位成功:返回true。否则返回false。
DWORD getFileSize(void)
这个函数用来获取被定位的文件的长度(字节数)。返回0xFFFFFFFF表示错误。
bool Read(LPVOID lpbuffer,DWORD len)
这个函数用来读取压缩包中当前被定位的文件,lpbuffer是已分配len字节的空间地址,len是lpbuffer的长度。
读取成功:返回true。否则返回false