




已阅读5页,还剩9页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第十三章补充CFileVersionMgr类FileVersionMgr.h#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); / 对产生文件的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 vector / 定义文件信息数组类型class CFileVersionMgr / 文件版本管理类public:static const int CREATE_VERSION;static const int UPDATE_VERSION; static const int OP_FLAG_INVALID; / 文件的操作标志 : 无效static const int OP_FLAG_VALID; / 文件的操作标志 : 有效static const int OP_FLAG_UPDATE; / 文件的操作标志 : 需要被更新char m_szWorkingDir255; / 当前管理的目录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); / 文件信息数据存盘(存成文本文件)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 *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 bWriteFile); / 压缩版本信息列表里的所有文件VOID CompressAll(char *pszDestDir, vector* pUpdateList);#endifFileVersionMgr.cpp#include FileVersionMgr.h#ifdef WIN32 #include #else#endif#include const int CFileVersionMgr:CREATE_VERSION = 0;const int CFileVersionMgr:UPDATE_VERSION = 1;const int CFileVersionMgr:OP_FLAG_INVALID = 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_FLAG_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 szSearch255; if(strlen(pszDir)=0) strcpy(szSearch , *.*); else strcpy(szSearch , pszDir); strcat(szSearch , /*.*); int hnd = _findfirst(szSearch , &filestruct); 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 , ); else strcpy(szFullName , ); if(!(filestruct.attrib & _A_SUBDIR) / 如果文件属性不是目录 char szDigest33; MD5String(szFullName , szDigest); / 取得MD5字符串 if(nFlag=CREATE_VERSION) / 如果是创建版本 _AddFileInfo(szFullName, szDigest, filestruct.size); else if(nFlag=UPDATE_VERSION) / 如果是更新版本 _UpdateFileInfo(szFullName, szDigest, filestruct.size); else / 发现子目录 if(strcmp( , .)!=0 & strcmp( , .)!=0) CheckDirFile(szFullName , nFlag); / 递归调用自身 while(!_findnext(hnd , &filestruct); return TRUE;#endif#ifdef LINUX / 如果是Linux平台 int nLen = strlen(pszDir); DIR *dir; if(nLen=0) dir = opendir(.); else dir = opendir(pszDir); if(dir!=NULL) int n; direct *dd; while(dd = readdir(dir) / 遍历目录里的所有文件, 结果存放在结构体dd里面 if(strcmp(dd-d_name , .)!=0 & strcmp(dd-d_name , .)!=0) char szFullName255; strcpy(szFullName , pszDir); if(pszDirnLen - 1!=/ & (nLen 0) strcat(szFullName , /); strcat(szFullName , dd-d_name); struct stat stat_p; stat(szFullName , &stat_p);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; char 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 else Log(ERR : Directory %s is not existn , pszDir); return 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_FileIndexpszFileName = 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 = &(m_FileListnIndex); if(strcmp(pInfo-szVersion , pszDigest)!=0) / MD5值不同 strcpy(pInfo-szVersion , pszDigest); pInfo-cFlag = OP_FLAG_UPDATE; / 设置操作标志为需要更新 else pInfo-cFlag = OP_FLAG_VALID; / 设置操作标志为有效 else _AddFileInfo(pszFileName, pszDigest, nSize); / 添加新文件 / 功能 : 保存文件信息列表到指定文本文件/ 注 : 文件信息列表中那些操作标志被设为无效的文件并不会被写入, 当维护当前管理目录/ 时, 如果删除了某些不再需要的文件, 那么在记录版本信息列表的文件里,这些文件也对应被/ 删除了.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-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(access(pszFile, 0)=-1) return FALSE; m_FileList.clear(); m_FileIndex.clear(); LoadVersionFile(&m_FileList, &m_FileIndex, m_szWorkingDir, pszFile);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); 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.size();/ 功能 : 从一个文本文件里读入文件信息列表, 并保存到传入的列表指针和索引指针里/ pFileList : 文件列表数组的指针/ pFileIdx : ID-列表数组下标的索引指针/ pszFileName : 文件名BOOL CFileVersionMgr:LoadVersionFile(vector *pFileList, map* pFileIdx, char *pszWorkingDir, char *pszFileName) ifstream in(pszFileName); / 按文本方式打开文件 if(in.is_open()=0) / 文件打开失败, 返回错误 Log(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.find(,); / 解析逗号间隔的字符串 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 info; 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;/ 功能 : 读入一个版本信息文件, 和现有的版本信息列表的内容做比对/ 如果发现版本已经发生变化, 则加入到一个更新列表中/ szCompareFile : 用来比较的版本信息文件名/ pUpdateList : 用来记录更新的列表/ pnTotalSize : 因为比较的过程会检查所有文件,所以可以计算好/ 所有要更新的文件累加起来的尺寸, 将来用于显示更新进度/ bBuilder : 一个标志决定比较的双方, 是新读入的文件比对现有/ 信息还是现有信息比对新读入的文件BOOL CFileVersionMgr:GenerateUpdateList(char *szCompareFile, vector* pUpdateList, int *pnTotalSize, BOOL bBuilder) vector CompareList; map CompareIdx; char szWorkingDir255; / 读入传入文件里包含的文件版本信息 if(!LoadVersionFile(&CompareList, &CompareIdx, szWorkingDir, szCompareFile) return FALSE; / 如果读入文件失败, 返回错误 if(strcmp(szWorkingDir , m_szWorkingDir)!=0) / 如果文件里记录的管理目录与现有的不同,发出一个警告 Log(Warning : Different Working Directory!n); vector* pListSrc = NULL; map* pIdxSrc = NULL; vector* pListDest = NULL; map* pIdxDest = NULL; if(bBuilder) / 决定新读入的文件和现有的版本信息, 谁和谁做比对 pListSrc = &CompareList; pIdxSrc = &CompareIdx; pListDest = &m_FileList; pIdxDest = &m_FileIndex; else pListSrc = &m_FileList; pIdxSrc = &m_FileIndex; pListDest = &CompareList; pIdxDest = &CompareIdx; / 比对开始 Log(Compare Src Size = %d , Dest Size = %dn, pListSrc-size(), pListDest-size(); int nFileSize =0; for(int n = 0; n size(); n+) / 遍历数组里所有文件 SFILE_INFO *pDestInfo = &(*pListDest)n); map:iterator it = pIdxSrc-find(pDestInfo-szID); if(it!=pIdxSrc-end() / 发现对应文件ID int nIndex = (*it).second; SFILE_INFO *pSrcInfo = &(*pListSrc)nIndex); if(strcmp(pDestInfo-szVersion , pSrcInfo-szVersion)!=0) pUpdateList-push_back(*pDestInfo); /如果MD5版本不同, 放入更新列表 nFileSize+=pDestInfo-dwSize; / 文件尺寸累加 else / 如果当前的文件ID没有发现, 表明是新添加的文件 pUpdateList-push_back(*pDestInfo); / 放入更新列表 nFileSize+=pDestInfo-dwSize; / 文件尺寸累加 *pnTotalSize = nFileSize; return TRUE;/ 功能 : 更新(或添加)某个文件的版本信息, 并马上重写文件/ pInfo : 文件信息的指针/ bWriteFile : 是否马上重写文件BOOL CFileVersionMgr:UpdateFileVersion(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 = &(m_FileListnIndex); strcpy(pFileInfo-szVersion, pInfo-szVersion); else / 添加新的文件版本信息到现有列表中 SFILE_INFO info; strcpy(info.szID, pInfo-szID); strcpy(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;/ 功能 : 按照指定文件更新信息列表(或当前文件信息列表)的内容, 把所有的文件/ 按照原有的目录结构压缩到指定目录中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) / 如果更新列表为空, 表示直接使用当前的文件信息列表 pCurList = &m_FileList; int nUpdate = 0; for(int n = 0; n size(); n+) SFILE_INFO *pInfo = &(*pCurList)n); 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 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+; 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, szDigest); char sz
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 政府保安公司合同(标准版)
- 轧制备品工中秋节后复工安全考核试卷含答案
- 煤层气测井测试工国庆节后复工安全考核试卷含答案
- 中小企业市场竞争分析及战略制定报告
- 飞机供氧系统调试工国庆节后复工安全考核试卷含答案
- 工程附加合同范本6篇
- 蒸吸工中秋节后复工安全考核试卷含答案
- 装载机操作技能理论考试题库
- 溶解乙炔生产工国庆节后复工安全考核试卷含答案
- 人教版高中化学课程目录清单
- 16949体系培训计划
- T/CAZG 003-2019亚洲象饲养管理技术规范
- 火锅店股东协议合同协议
- 高中英语3500词词汇
- 四川遂宁历年中考作文题与审题指导(2004-2024)
- 电梯曳引钢丝绳维护保养制度
- 老年人防烫伤安全教育
- 2024年福州地铁集团有限公司招聘笔试真题
- 第二单元第二节元素教学设计-2024-2025学年九年级化学鲁教版上册
- 2025少先队基础知识试题库及参考答案
- 护理人员中医技术使用手册(2024版)
评论
0/150
提交评论