收藏 分享(赏)

第十三章补充——CFileVersionMgr类.doc

上传人:j35w19 文档编号:7240840 上传时间:2019-05-10 格式:DOC 页数:14 大小:96KB
下载 相关 举报
第十三章补充——CFileVersionMgr类.doc_第1页
第1页 / 共14页
第十三章补充——CFileVersionMgr类.doc_第2页
第2页 / 共14页
第十三章补充——CFileVersionMgr类.doc_第3页
第3页 / 共14页
第十三章补充——CFileVersionMgr类.doc_第4页
第4页 / 共14页
第十三章补充——CFileVersionMgr类.doc_第5页
第5页 / 共14页
点击查看更多>>
资源描述

1、第十三章补充 CFileVersionMgr 类#ifndef CLASS_FILEVERSION#define CLASS_FILEVERSION#include “zstream.h“ / 包含 glib 的相关头文件extern “C“ #include “global.h“ / 包含 MD5 算法的相关头文件#include “md5.h“#include “util.h“#include #include #include #include using namespace std;VOID MD5String(char *pszFile , char *szDigest); / 对产

2、生文件的 md5 字符串的简单封装int CompressFile(char *pszSrc , char *pszDest); / 封装使用 glib 对文件的压缩和解压的操作过程VOID UncompressFile(char *pszSrc , char *pszDest); / 记录文件有关信息的结构体struct SFILE_INFOchar szID255; / 文件 ID, 由目录名+文件名组成char szVersion33; / 版本字符串 ,也就是 MD5 值DWORD dwSize; / 文件尺寸char cFlag; / 操作标志;#define FILE_ARRAY

3、vector / 定义文件信息数组类型class CFileVersionMgr / 文件版本管理类public:static const int CREATE_VERSION;static const int UPDATE_VERSION;FileVersionMgr.hstatic const int OP_FLAG_INVALID; / 文件的操作标志 : 无效static const int OP_FLAG_VALID; / 文件的操作标志 : 有效static const int OP_FLAG_UPDATE; / 文件的操作标志 : 需要被更新char m_szWorkingDir

4、255; / 当前管理的目录FILE_ARRAY m_FileList; / 文件列表 map m_FileIndex; / 从字符串 ID 索引到文件列表数组的下标private:/ 添加单个文件信息到列表VOID _AddFileInfo(char *pszFileName , char *pszMD5 , int nSize);/ 更新已有的单个文件信息VOID _UpdateFileInfo(char *pszFileName , char *pszMD5 , int nSize);VOID _Data2Txt(char *pszFileName); / 文件信息数据存盘(存成文本文件

5、)public:CFileVersionMgr();CFileVersionMgr();VOID ClearFlag(); / 设置当前文件列表里所有文件的操作标志为无效VOID Data2File(char *pszFileName, BOOL bText); / 存盘函数BOOL CheckDirFile(char *pszDir, int nFlag); / 递归一个目录里所有文件 (包含)子目录VOID CreateFileVersionInfo(char *pszDir, int nFlag); / 对指定目录创建版本信息BOOL LoadFileVersionInfo(char *

6、pszFile); / 从文件里读取版本信息BOOL LoadVersionFile(vector *pCompareList, map* pCompareIdx,char *pszWorkingDir , char *pszFile);BOOL GenerateUpdateList(char *szCompareFile , vector *pUpdateList , int *pnTotalSize, BOOL bBuilder = FALSE);/ 更新某个文件的版本信息, 并重写版本文件BOOL UpdateFileVersion(SFILE_INFO *pInfo , BOOL bW

7、riteFile);/ 压缩版本信息列表里的所有文件VOID CompressAll(char *pszDestDir, vector* pUpdateList);#endif#include “FileVersionMgr.h“#ifdef WIN32#include FileVersionMgr.cpp#else#endif#include const int CFileVersionMgr:CREATE_VERSION = 0;const int CFileVersionMgr:UPDATE_VERSION = 1;const int CFileVersionMgr:OP_FLAG_IN

8、VALID = 0;const int CFileVersionMgr:OP_FLAG_VALID = 1;const int CFileVersionMgr:OP_FLAG_UPDATE = 2;CFileVersionMgr:CFileVersionMgr()strcpy(m_szWorkingDir , “NULL“); / 管理目录初始化为”NULL”CFileVersionMgr:CFileVersionMgr() / 设置文件信息列表里所有文件的操作标志为无效VOID CFileVersionMgr:ClearFlag()for(int n = 0 ; n cFlag = OP_F

9、LAG_INVALID; / 置为无效/ 功能 : 遍历指定目录所有文件, 并按照 nFlag 执行特定操作/ 注 : 里面包含了两套目录操作函数,分别对应于 windows 操作系统和 linux 操作系统/ 因为要计算文件的 MD5 值, 该函数会可能会执行比较长的时间 , 取决于文件的数量和大小BOOL CFileVersionMgr:CheckDirFile(char *pszDir , int nFlag)#ifdef WIN32 / 如果是 windows 操作系统 _finddata_t filestruct;int p = 0;int fn = 0;char szSearch2

10、55;if(strlen(pszDir)=0)strcpy(szSearch , “*.*“);elsestrcpy(szSearch , pszDir);strcat(szSearch , “/*.*“);int hnd = _findfirst(szSearch , if(hnd=-1) / Log(“no file found in dir %sn“ , szSearch);return FALSE;do char szFullName255;if(strlen(pszDir) 0)sprintf(szFullName , “%s/%s“ , pszDir , filestruct.na

11、me);elsestrcpy(szFullName , filestruct.name);if(!(filestruct.attrib MD5String(szFullName , szDigest); / 取得 MD5 字符串if(nFlag=CREATE_VERSION) / 如果是创建版本_AddFileInfo(szFullName, szDigest, filestruct.size);else if(nFlag=UPDATE_VERSION) / 如果是更新版本_UpdateFileInfo(szFullName, szDigest, filestruct.size);else /

12、 发现子目录if(strcmp(filestruct.name , “)!=0 / 递归调用自身while(!_findnext(hnd , return TRUE;#endif#ifdef LINUX / 如果是 Linux 平台int nLen = strlen(pszDir);DIR *dir;if(nLen=0)dir = opendir(“.“);elsedir = opendir(pszDir);if(dir!=NULL)int n;direct *dd;while(dd = readdir(dir) / 遍历目录里的所有文件, 结果存放在结构体 dd 里面if(strcmp(dd

13、-d_name , “.“)!=0 strcpy(szFullName , pszDir);if(pszDirnLen - 1!=/ strcat(szFullName , dd-d_name);struct stat stat_p;stat(szFullName , if(S_ISDIR(stat_p.st_mode) / 文件属性检查函数与 windows 不同CheckDirFile(szFullName , nFlag); / 如果是目录, 递归自身else if(S_ISREG(stat_p.st_mode) / 是文件int nFileSize = stat_p.st_size;c

14、har szDigest33;MD5String(szFullName , szDigest);if(nFlag=CREATE_VERSION)_AddFileInfo(szFullName , szDigest , nFileSize);else if(nFlag=UPDATE_VERSION)_UpdateFileInfo(szFullName , szDigest , nFileSize); / end !(“.“|“) / end white / dir is exist elseLog(“ERR : Directory %s is not existn“ , pszDir);retu

15、rn TRUE;#endif/ 功能 : 添加新的文件信息到列表中VOID CFileVersionMgr:_AddFileInfo(char *pszFileName , char *pszDigest , int nSize)SFILE_INFO info;strcpy(info.szID, pszFileName);strcpy(info.szVersion , pszDigest);info.dwSize = nSize;info.cFlag = OP_FLAG_UPDATE; / 操作标志初始化为需要更新m_FileList.push_back(info);m_FileIndexps

16、zFileName = m_FileList.size() - 1;/ 功能 : 更新已有的单个文件信息VOID CFileVersionMgr:_UpdateFileInfo(char *pszFileName , char *pszDigest , int nSize)map:iterator it = m_FileIndex.find(pszFileName);if(it!=m_FileIndex.end() / 如果文件存在int nIndex = (*it).second;SFILE_INFO *pInfo = if(strcmp(pInfo-szVersion , pszDiges

17、t)!=0) / MD5 值不同strcpy(pInfo-szVersion , pszDigest);pInfo-cFlag = OP_FLAG_UPDATE; / 设置操作标志为 需要更新elsepInfo-cFlag = OP_FLAG_VALID; / 设置操作标志为 有效else_AddFileInfo(pszFileName, pszDigest, nSize); / 添加新文件/ 功能 : 保存文件信息列表到指定文本文件/ 注 : 文件信息列表中那些操作标志被设为无效的文件并不会被写入, 当维护当前管理目录/ 时, 如果删除了某些不再需要的文件, 那么在记录版本信息列表的文件里,

18、这些文件也对应被/ 删除了.VOID CFileVersionMgr:_Data2Txt(char *pszFileName)FILE *fp = fopen(pszFileName, “wt“);if(fp=NULL) return;fprintf(fp, “%sn“, m_szWorkingDir); / 在首行记录下当前管理目录int nValid = 0;for(int n = 0 ; n cFlag!=OP_FLAG_INVALID) / 如果文件操作标志不是无效fprintf(fp , “%s,%s,%dn“, pInfo-szID, pInfo-szVersion, pInfo-

19、dwSize);nValid+;fclose(fp);/ Log(“Write List , Total = %dn“, nValid);VOID CFileVersionMgr:Data2File(char *pszFileName, BOOL bText)if(bText) _Data2Txt(pszFileName); / 写成文本文件else _Data2Bin(pszFileName); / 写成二进制文件, 目前并没有使用/ 功能 : 从指定文件中读入版本信息BOOL CFileVersionMgr:LoadFileVersionInfo(char *pszFile)if(acce

20、ss(pszFile, 0)=-1)return FALSE;m_FileList.clear();m_FileIndex.clear();LoadVersionFile(Log(“File Info Load = %dn“, m_FileList.size();return TRUE;/ 功能 : 从指定目录创建文件版本信息列表VOID CFileVersionMgr:CreateFileVersionInfo(char *pszDir, int nFlag)if(access(pszDir, 0)=-1) / 如果目录不存在, 返回错误Log(“Directory not exist!n“

21、);return;if(nFlag=CREATE_VERSION) / 如果是重新创建版本/ 清除现有记录m_FileList.clear();m_FileIndex.clear(); strcpy(m_szWorkingDir, pszDir);char szCurDir255;getcwd(szCurDir, 255); / 保存程序的当前目录chdir(pszDir); / 进入要遍历的目录( 使它成为当前根目录)CheckDirFile(“, nFlag);chdir(szCurDir); / 恢复成刚才保存的目录Log(“Total File = n“, m_FileList.siz

22、e();/ 功能 : 从一个文本文件里读入文件信息列表, 并保存到传入的列表指针和索引指针里/ pFileList : 文件列表数组的指针/ pFileIdx : ID-列表数组下标的索引指针/ pszFileName : 文件名BOOL CFileVersionMgr:LoadVersionFile(vector *pFileList, map* pFileIdx, char *pszWorkingDir, char *pszFileName)ifstream in(pszFileName); / 按文本方式打开文件if(in.is_open()=0) / 文件打开失败, 返回错误Log(“

23、Open Compare File Error n“, pszFileName);return FALSE;/ 依次读入并解析文件版本信息 : ID,MD5 版本,尺寸char szLine512;in.getline(szLine , 512);string strRunDir = szLine;strcpy(pszWorkingDir , strRunDir.c_str();while(!in.eof()in.getline(szLine , 512);string strLine = szLine;if(strLine.size()=0) break;int p = strLine.fi

24、nd(“,“); / 解析逗号间隔的字符串string strLeft = strLine.substr(0 , p);string strRight = strLine.substr(p + 1 , strLine.size() - p - 1);p = strRight.find(“,“);string strVer = strRight.substr(0 , p);string strSize = strRight.substr(p + 1 , strRight.size() - p - 1);int nSize = atoi(strSize.c_str();SFILE_INFO inf

25、o;strcpy(info.szID , strLeft.c_str();strcpy(info.szVersion , strVer.c_str(); info.dwSize = nSize;info.cFlag = OP_FLAG_VALID; / 已经读入的文件信息, 操作标志初始化为有效pFileList-push_back(info);(*pFileIdx)info.szID = pFileList-size() - 1;/ Log(“ID , Ver = n“, strLeft.c_str() , info.szVersion);in.close();return TRUE;/ 功

26、能 : 读入一个版本信息文件, 和现有的版本信息列表的内容做比对/ 如果发现版本已经发生变化, 则加入到一个更新列表中/ szCompareFile : 用来比较的版本信息文件名/ pUpdateList : 用来记录更新的列表/ pnTotalSize : 因为比较的过程会检查所有文件,所以可以计算好/ 所有要更新的文件累加起来的尺寸, 将来用于显示更新进度/ bBuilder : 一个标志决定比较的双方 , 是新读入的文件比对现有/ 信息还是现有信息比对新读入的文件BOOL CFileVersionMgr:GenerateUpdateList(char *szCompareFile, ve

27、ctor* pUpdateList, int *pnTotalSize, BOOL bBuilder)vector CompareList;map CompareIdx;char szWorkingDir255; / 读入传入文件里包含的文件版本信息if(!LoadVersionFile( / 如果读入文件失败, 返回错误if(strcmp(szWorkingDir , m_szWorkingDir)!=0) / 如果文件里记录的管理目录与现有的不同,发出一个警告Log(“Warning : Different Working Directory!n“);vector* pListSrc =

28、NULL;map* pIdxSrc = NULL;vector* pListDest = NULL;map* pIdxDest = NULL;if(bBuilder) / 决定新读入的文件和现有的版本信息, 谁和谁做比对pListSrc = pIdxSrc = pListDest = pIdxDest = elsepListSrc = pIdxSrc = pListDest = pIdxDest = / 比对开始Log(“Compare Src Size = %d , Dest Size = %dn“, pListSrc-size(), pListDest-size();int nFileSi

29、ze =0;for(int n = 0; n size(); n+) / 遍历数组里所有文件SFILE_INFO *pDestInfo = map:iterator it = pIdxSrc-find(pDestInfo-szID);if(it!=pIdxSrc-end() / 发现对应文件 IDint nIndex = (*it).second;SFILE_INFO *pSrcInfo = if(strcmp(pDestInfo-szVersion , pSrcInfo-szVersion)!=0)pUpdateList-push_back(*pDestInfo); /如果 MD5 版本不同

30、, 放入更新列表nFileSize+=pDestInfo-dwSize; / 文件尺寸累加else / 如果当前的文件 ID 没有发现, 表明是新添加的文件pUpdateList-push_back(*pDestInfo); / 放入更新列表nFileSize+=pDestInfo-dwSize; / 文件尺寸累加*pnTotalSize = nFileSize;return TRUE;/ 功能 : 更新(或添加)某个文件的版本信息, 并马上重写文件/ pInfo : 文件信息的指针/ bWriteFile : 是否马上重写文件BOOL CFileVersionMgr:UpdateFileVe

31、rsion(SFILE_INFO *pInfo, BOOL bWriteFile)map:iterator it = m_FileIndex.find(pInfo-szID);if(it!=m_FileIndex.end() / 此文件 ID 已存在, 进行更新int nIndex = (*it).second;SFILE_INFO *pFileInfo = strcpy(pFileInfo-szVersion, pInfo-szVersion);else / 添加新的文件版本信息到现有列表中SFILE_INFO info;strcpy(info.szID, pInfo-szID);strcp

32、y(info.szVersion, pInfo-szVersion);info.dwSize = pInfo-dwSize;m_FileList.push_back(info);m_FileIndexinfo.szID = m_FileList.size();if(bWriteFile)/ 写入版本信息文件(就是重写整个文件), 因为该函数是在更新过程被调用的, 文件一旦 / 被更新完就会马上写入文件, 如果玩家马上退出程序, 更新结果也得以保存Data2File(“VerInfo.rec“, TRUE);return TRUE;/ 功能 : 按照指定文件更新信息列表(或当前文件信息列表)的内

33、容, 把所有的文件/ 按照原有的目录结构压缩到指定目录中VOID CFileVersionMgr:CompressAll(char *pszDestDir, vector* pUpdateList)string strDest = pszDestDir; / 目的地目录 string strSrc = m_szWorkingDir; / 取得当前目录strDest+=“/“;strSrc+=“/“;char szSrcFile255, char szDestFile255;vector* pCurList = pUpdateList;if(pCurList=NULL) / 如果更新列表为空,

34、表示直接使用当前的文件信息列表pCurList = int nUpdate = 0;for(int n = 0; n size(); n+)SFILE_INFO *pInfo = if(pInfo-cFlag!=OP_FLAG_UPDATE) continue; / 如果文件的操作标志不是需要升级, / 则跳过该文件strcpy(szSrcFile , strSrc.c_str(); strcat(szSrcFile , pInfo-szID);strcpy(szDestFile , strDest.c_str(); strcat(szDestFile , pInfo-szID);string

35、 strDestFile = szDestFile;int p = strDestFile.rfind(/);if(p!=-1)string strDir = strDestFile.substr(0 , p);Util_MakeDir(strDir.c_str(); / 如果目标目录或其子目录并不存在, 则创建之Log(“Compress %sn“ , szSrcFile);CompressFile(szSrcFile , szDestFile);pInfo-dwSize = Util_GetFileSizeByName(szDestFile); / 设置为压缩之后的文件尺寸nUpdate+

36、;Log(“File Update and Compress Total = %dn“, nUpdate);/ 生成记录版本信息的文件Data2File(“VerComp.dat“ , TRUE); / 生成版本文件string strFile = strDest;strFile+=“VerComp.dat“;CompressFile(“VerComp.dat“ , (char*)strFile.c_str(); / 压缩版本文件到目的地目录/ 把版本文件的 MD5 单独记录下来到一个文件 ver char szDigest33; MD5String(“VerComp.dat“, szDige

37、st);char szVerFile255 = “ver“;FILE *fp = fopen(szVerFile, “wt“); / 写入文件fprintf(fp, “%s“, szDigest);fclose(fp);strFile = strDest;strFile+=szVerFile;CompressFile(szVerFile, (char*)strFile.c_str(); 压缩后保存到目的地目录/ 功能 : 使用 glib 压缩文件/ 注:ozstream 是一个封装了 glib 操作的类库, 是基于 stream 操作的, 附带光盘有相关文件int CompressFile(c

38、har *pszSrc , char *pszDest)ozstream out(pszDest);FILE *fp = fopen(pszSrc , “rb“);if(fp=NULL)Log(“ERR : Open Src File %s Fail!n“ , pszSrc);return 0;int buf_size = 1024 * 32;char *buf = new charbuf_size;int nSize = 0;while(1)int len = fread(buf , 1 , buf_size , fp);nSize+=out.write(buf , len);if(feof

39、(fp) break;fclose(fp);out.close();delete buf;return nSize;/ 功能 : 使用 glib 解压缩文件VOID UncompressFile(char *pszSrc , char *pszDest)int buf_size = 1024 * 32;char *buf = new charbuf_size;izstream in(pszSrc);FILE *fp = fopen(pszDest , “wb“);while(1)int n = in.read(buf , buf_size);fwrite(buf , 1 , n , fp);i

40、f(gzeof(in.fp() break;in.close();fclose(fp);delete buf;/ 功能 : 获得文件的 MD5 字符串 , 注 : MDFile()是 MD5 算法里提供的计算函数, 产生的是 128 位/ 数字, 为了使用方便, 这里把它转成 32 个字节长的字符串VOID MD5String(char *pszFile , char *pszDigest)BYTE btDigest16; MDFile(pszFile , (char*)btDigest); / 产生 128 位数字, 保存到 16 个字节的空间里for (int i = 0; i 16; i+)sprintf(pszDigest + i * 2 , “%02x“, btDigesti); / 按照 16 进制的格式写成字符串pszDigest32 = 0;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报