Windows下保持目录结构的文件备份算法
来源:互联网 发布:淘宝客服统计销售额 编辑:程序博客网 时间:2024/06/03 18:05
Windows下保持目录结构的文件备份算法
作者:成晓旭
最近要做最一些数据处理工作,需要在大量的文件中,处理项目特定的文件数据库。由于文件数据库是散步在几百G的其他数据文件中,为便于进行数据库文件的备份,处理,写了一个简单的文件遍历、自动备份的小程序:确保备份之后的文件目录结构,与原来的目录结构完全一样,因为此文件的目录结构是项目的数据关系地图,关乎着很多重要的信息待后续进行分析、统计。
貌似Windows提供的文件复制API,不能自动创建目标文件的目录结构。本人比较懒惰,也没自己去研究这个问题,不知道是否还有其他的文件操作API,能够一步到位。如果有知道的朋友麻烦告诉一下。谢谢!
(其实,有一种体会:程序写的越久,胆子反而越小。大家会发现,下面所示的函数中,起实质性左右的代码往往还不及总代码行数的一半,另外的一大半代码,都是用于保护程序不要出错、检查边界、或者出于运行效率考虑。)
完整源码已经上传到CSDN资源中心:http://download.csdn.net/detail/cxxsoft/4287500
涉及到两个核心的处理过程。
其一,指定初始路径的文件遍历:
//从指定路径开始,遍历特定扩展名的文件
function TForm1.EnumFileInQueue(const strInitPath, fileExName: string;
var dwgDBFileBuffer: TStringBuffer; var dirNumber,
fileNumber: DWord): boolean;
const
Max_Buffer = $FFFF;
var
searchRec:TSearchRec;
found:Integer;
tmpStr,strMsg,strPath,strPathFile:String;
strTypeName,strBoxDir,strBoxCode,strFileName:string;
curDir:PChar;
dirs:TQueue;
begin
Result:=true;
fileNumber := 0;//查找结果(文件数)
dirNumber := 0;
dirs:=TQueue.Create;//创建目录队列
SetLength(dwgDBFileBuffer,0);
SetLength(dwgDBFileBuffer,Max_Buffer);
dirs.Push(Pointer(strInitPath));//将起始搜索路径入队
curDir:=dirs.Pop;//出队
while (curDir<> nil) do
begin
tmpStr:=StrPas(curDir)+'*.*';
//tmpStr:=StrPas(curDir)+'*.pdf';
//在当前目录查找第一个文件、子目录
//FillChar(searchRec,SizeOf(TSearchRec),'0');
//showLogToMemo(tmpStr);
found:=FindFirst(tmpStr,faAnyFile,searchRec);
while found=0 do
//找到了一个文件或目录后
begin
//如果找到的是个目录
if (searchRec.Attr and faDirectory)<>0 then
begin
if (searchRec.Name <> '.') and (searchRec.Name <> '..') then
begin
strPath := StrPas(curDir)+''+searchRec.Name+'\';
tmpStr := strPath;
dirs.Push(StrNew(PChar(tmpStr)));
Inc(dirNumber);
//strMsg := Format('%s',[strPath]);
showLogToMemo(searchRec.Name);
end;
end
//如果找到的是个文件
else
begin
//把找到的文件加到Memo控件
strPathFile := StrPas(curDir)+''+searchRec.Name;
//保存指定扩展名的文件
if Pos(fileExName,strPathFile) <> 0 then
begin
dwgDBFileBuffer[fileNumber] := strPathFile;
Inc(fileNumber);
if fileNumber >= Max_Buffer then break;
SetHintCaption(Format('load pdf File:%d',[fileNumber]));
end;
end;
//查找下一个文件或目录
found:=FindNext(searchRec);
end;
{当前目录找到后,如果队列中没有数据,则表示全部找到了;
否则就是还有子目录未查找,取一个出来继续查找。}
if dirs.Count > 0 then
curDir:=dirs.Pop
else
curDir:=nil;
Application.ProcessMessages();
if fileNumber >= Max_Buffer then break;
end;
//释放资源
dirs.Free;
FindClose(searchRec);
end;
其二:递归创建目录结构,并复制正确的文件到对应的目录:
//根据完整路径复制文件,如果目录不存在,则自动创建目录
function TForm1.CopyDBFileByCompletePath(const strFilePath: string): boolean;
const
Backup_Path_Name = 'backup';
var
strNewFile,strTempDir:string;
strHead,strTail:string;
pHead:integer;
begin
Result := false;
//判断参数
if NOT FileExists(strFilePath) then Exit;
pHead := Pos(STR_Dwg_Dat,strFilePath);
if (pHead > 0) then
begin
strHead := Copy(strFilePath,1,pHead-1);
strTail := Copy(strFilePath,pHead,Length(strFilePath));
end;
strNewFile := strHead + Backup_Path_Name + '\' + strTail;
strNewFile := ReplaceStr(strNewFile,'/','\');
strTempDir := ExtractFilePath(strNewFile);
if NOT DirectoryExists(strTempDir) then
begin
//递归创建目录结构
strTail := strNewFile;
strTempDir := '';
pHead := Pos('\',strTail);
while (pHead <> 0) do
begin
strHead := Copy(strTail,1,pHead);
strTail := Copy(strTail,pHead+1,Length(strTail));
strTempDir := strTempDir + strHead;
if NOT DirectoryExists(strTempDir) then
CreateDir(strTempDir);
pHead := Pos('\',strTail);
end;
end;
//强制复制文件,已存在的同名文件将被自动覆盖
Result := CopyFile(PWideChar(strFilePath),PWideChar(strNewFile),false);
end;
- Windows下保持目录结构的文件备份算法
- Linux下备份项目,保持结构,选择性复制部分文件
- [C#] 筛选复制文件并保持原有的目录结构
- DB2的目录结构(Windows下)
- 输出目录下的文件树形结构
- Linux下的文件目录结构详解
- 获取一个目录下的文件结构
- Linux下的文件目录结构简介
- Windows下复制目录结构
- rsync 提取目录结构而不包括目录下的文件
- Windows环境扫描目录下的文件
- 树莓派访问Windows下的目录文件
- Java 批量反编译class文件,并保持目录结构
- Java 批量反编译class文件,并保持目录结构
- 批处理备份某一目录下最新的一个文件
- shell 备份指定目录下的增量文件
- windows下创建目录,备份文档脚本
- linux下备份一个目录下所有文件及目录
- c++中利用宏来声明和定义变量
- Linux 的文件权限与目录配置
- Spring模拟(AOP)
- Android:Unable to open sync connection!
- ClassNotFoundException: org.hibernate.hql.ast.HqlToken
- Windows下保持目录结构的文件备份算法
- mfc使用opencv时CImage(CvvImage)取消以后的替代方法及error C2039: “DrawToHDC”: 不是“ATL::CImage”的成员
- 全面的Linux的学习资料
- 在webLogic 10.3中部署Hibernate 3.5出现 ClassNotFoundException解决办法
- java之HeapByteBuffer&DirectByteBuffer以及回收DirectByteBuffer
- 程序员编程艺术:第九章、闲话链表追赶问题
- mini2440 linux 内存布局
- Ubuntu下怎么设置Root超级账户密码
- 淘宝下单高并发解决方案