文件夹压缩问题(10分)

  • 主题发起人 主题发起人 coolingxyz
  • 开始时间 开始时间
C

coolingxyz

Unregistered / Unconfirmed
GUEST, unregistred user!
一些解压缩软件都支持文件夹解压缩,有的还支持从压缩包中单独提取一个文件,或则把一个文件加入压缩包中。<br><br>我想同一路径下的文件压缩合并成一个文件,难度不是很大,只要把文件一个一个压缩,然后合并到一起就可以了,但它们在被单独提取时,怎样的结构更方便和有效,是比较麻烦的。还有如果是一个文件夹,而且文件夹下还有子文件夹及文件的话,我觉得很麻烦了。<br><br>我找了一些类似的控件,但没有源代码,所以学不到什么东西。<br><br>有没有这样的源代码,可以支持文件夹压缩的和单独文件提取、加入的?<br><br>如果哪位朋友有的话,能不能发一份给我,或则给个网址。<br><br>这两天问了好几个问题,但都没有很好的解决,只有这么点分了。谢谢<br>
 
就10分,你也真好意思。VCLZIP2.23有源代码,自己找找看
 
我比较菜,所以手头没有分了呀。<br><br>如果仅仅解决了部分问题的也可以,同样可以给分,分数还可以再加(现在我就去赚分)。<br><br>主要就是文件夹解压缩的问题。<br>
 
我以前开发过的部分源码<br>可以压缩文件、文件夹<br><br><br>&nbsp; TCompFileInfo = record &nbsp; &nbsp; &nbsp; &nbsp;//压缩文件记录<br>&nbsp; &nbsp; Name &nbsp; &nbsp;: string; &nbsp; &nbsp; &nbsp;//文件名<br>&nbsp; &nbsp; Attr &nbsp; &nbsp;: string; &nbsp; &nbsp; &nbsp;//属性<br>&nbsp; &nbsp; Content : string; &nbsp; &nbsp; &nbsp; //内容<br>&nbsp; end;<br><br><br>procedure AddDirToPackage(SouDir,DestFile:string);<br>var FileList:TStrings;<br>&nbsp; i:integer;<br>&nbsp; FileInfo:TCompFileInfo;<br>begin<br>&nbsp; if DirectoryExists(SouDir)=False then exit;<br>&nbsp; FileList:=TStringList.Create;<br>&nbsp; try<br>&nbsp; &nbsp; FindFile(IncludeTrailingPathDelimiter(SouDir)+'*.*',True,True,faAnyFile,FileList);<br>&nbsp; &nbsp; for i:=0 to FileList.Count-1 do<br>&nbsp; &nbsp; &nbsp; AddFileToPackage(FileList.Strings,DestFile,ExtractFilePath(SouDir));<br>&nbsp; finally<br>&nbsp; &nbsp; FileList.Free;<br>&nbsp; end;<br>end;<br><br><br>procedure CompressFile(FileName:string;var Str:string);<br>var<br>&nbsp; SourceStream: TCompressionStream;<br>&nbsp; FileStream,DestStream: TMemoryStream;<br>&nbsp; Count:LongWord;<br>Begin<br>&nbsp; if FileExists(FileName)=False then exit;<br>&nbsp; DestStream := TMemoryStream.Create;<br>&nbsp; FileStream := TMemoryStream.Create;<br>&nbsp; FileStream.LoadFromFile(FileName);<br>&nbsp; Count := FileStream.Size;<br>&nbsp; SourceStream:=TCompressionStream.Create(clFastest,DestStream);<br>&nbsp; Try<br>&nbsp; &nbsp; FileStream.SaveToStream(SourceStream);<br>&nbsp; &nbsp; SourceStream.Free;<br>&nbsp; &nbsp; FileStream.Clear;<br>&nbsp; &nbsp; FileStream.WriteBuffer(Count,SizeOf(Count));<br>&nbsp; &nbsp; FileStream.CopyFrom(DestStream, 0);<br>&nbsp; &nbsp; Count := FileStream.Size;<br>&nbsp; &nbsp; FileStream.Position:=0;<br>&nbsp; &nbsp; SetLength(Str,Count);<br>&nbsp; &nbsp; FileStream.ReadBuffer(Str[1],Count);<br>&nbsp; finally<br>&nbsp; &nbsp; DestStream.Free;<br>&nbsp; &nbsp; FileStream.Free;<br>&nbsp; end;<br>end;<br><br>function File_AddString(iFileHandle:integer;Str:String):Boolean;<br>var<br>&nbsp; FilePos,RecLen:LongWord;<br>begin<br>&nbsp; FilePos:=FileSeek(iFileHandle,0,1); &nbsp;//保存文件当前指针位置<br>&nbsp; RecLen:=Length(Str);<br>&nbsp; Result:=(FileWrite(iFileHandle, RecLen, SizeOf(RecLen))&gt;-1) and<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (FileWrite(iFileHandle, Str[1], RecLen)&gt;-1);<br>&nbsp; if Result=False then<br>&nbsp; &nbsp; FileSeek(iFileHandle,FilePos,0);<br>end;<br><br><br>function AddFileToPackage(SouFile,DestFile:string;RootPath:string=''):boolean;<br>var iFileHandle:integer;<br>&nbsp; FileInfo:TCompFileInfo;<br>begin<br>&nbsp; if FileDirExists(SouFile)=False then exit;<br><br>&nbsp; if FileExists(DestFile) then<br>&nbsp; &nbsp; iFileHandle:=FileOpen(DestFile,fmOpenWrite)<br>&nbsp; else<br>&nbsp; &nbsp; iFileHandle:=FileCreate(DestFile);<br>&nbsp; try<br>&nbsp; &nbsp; FileSeek(iFileHandle,0,2);<br>&nbsp; &nbsp; if RootPath='' then<br>&nbsp; &nbsp; &nbsp; FileInfo.Name:=ExtractFileName(SouFile)<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; FileInfo.Name:=RightStr(SouFile, Length(SouFile)-Length(RootPath));<br><br>&nbsp; &nbsp; FileInfo.Attr:=IntToStr(FileGetAttr(SouFile));<br>&nbsp; &nbsp; if DirectoryExists(SouFile) then begin<br>&nbsp; &nbsp; &nbsp; FileInfo.Name:=IncludeTrailingPathDelimiter(Fileinfo.Name);<br>&nbsp; &nbsp; &nbsp; FileInfo.Content:='';<br>&nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; CompressFile(SouFile,FileInfo.Content);<br><br>&nbsp; &nbsp; File_AddString(iFileHandle,FileInfo.Name);<br>&nbsp; &nbsp; File_AddString(iFileHandle,FileInfo.Attr);<br>&nbsp; &nbsp; File_AddString(iFileHandle,FileInfo.Content);<br>&nbsp; finally<br>&nbsp; &nbsp; FileClose(iFileHandle);<br>&nbsp; end;<br>end;<br><br><br>调用<br><br>&nbsp; AddFileToPackage('e:/我的程序/djy/ksxt/CurPaper','e:/我的程序/djy/cs/install/client.z');<br>&nbsp; AddDirToPackage('e:/我的程序/djy/ksxt/TEST','e:/我的程序/djy/cs/install/client.z');<br>
 
接上<br>解压函数<br><br>procedure DeCompress1(CompressFile,DestPath:string);<br>var<br>&nbsp; iFileHandle,FileSize:integer;<br>&nbsp; FileInfo:TCompFileInfo;<br>begin<br>&nbsp; if FileExists(CompressFile)=False then exit;<br>&nbsp; if DirectoryExists(DestPath)=False then ForceDirectories(DestPath);<br>&nbsp; FileSize:=GetFileSize(CompressFile);<br>&nbsp; iFileHandle:=CreateFile(pchar(CompressFile),GENERIC_READ,0,nil,OPEN_EXISTING ,FILE_ATTRIBUTE_NORMAL,0); //ofOpenExisting);<br>&nbsp; try<br>&nbsp; &nbsp; while FileSeek(iFileHandle,0,spCurrent)&lt;FileSize do begin<br>&nbsp; &nbsp; &nbsp; File_LoadString(iFileHandle,FileSize,FileInfo.Name);<br>&nbsp; &nbsp; &nbsp; Form1.Label3.Caption:='正在安装 '+FileInfo.Name;<br>&nbsp; &nbsp; &nbsp; Form1.ProgressBar1.Progress:=Form1.ProgressBar1.Progress+1;<br>&nbsp; &nbsp; &nbsp; Form1.ProgressBar1.Update;<br>&nbsp; &nbsp; &nbsp; Form1.Label3.Update;<br>&nbsp; &nbsp; &nbsp; if Pos(':',FileInfo.Name)=0 then<br>&nbsp; &nbsp; &nbsp; &nbsp; FileInfo.Name:=IncludeTrailingPathDelimiter(DestPath)+FileInfo.Name;<br>&nbsp; &nbsp; &nbsp; File_LoadString(iFileHandle,FileSize,FileInfo.Attr);<br>&nbsp; &nbsp; &nbsp; File_LoadString(iFileHandle,FileSize,FileInfo.Content);<br>&nbsp; &nbsp; &nbsp; if Copy(FileInfo.Name, Length(FileInfo.Name),1)='/' then<br>&nbsp; &nbsp; &nbsp; &nbsp; ForceDirectories(ExcludeTrailingPathDelimiter(FileInfo.Name))<br>&nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; DeCompressStr(FileInfo.Content,FileInfo.Name);<br>&nbsp; &nbsp; end;<br><br>&nbsp; finally<br>&nbsp; &nbsp; FileClose(iFileHandle);<br>&nbsp; end;<br>end;<br><br>调用<br>DeCompress1('c:/abc.z', 'c:/abc');
 
To xuhao1,非常感谢你的回复,但还有一些疑问!<br><br>procedure AddDirToPackage(SouDir,DestFile:string);<br>var FileList:TStrings;<br>&nbsp; i:integer;<br>&nbsp; FileInfo:TCompFileInfo;<br>begin<br>&nbsp; if DirectoryExists(SouDir)=False then exit;<br>&nbsp; FileList:=TStringList.Create;<br>&nbsp; try<br>&nbsp; &nbsp; FindFile(IncludeTrailingPathDelimiter(SouDir)+'*.*',True,True,faAnyFile,FileList);//这个不理解,也没有找到帮助<br>&nbsp; &nbsp; for i:=0 to FileList.Count-1 do<br>&nbsp; &nbsp; &nbsp; AddFileToPackage(FileList.Strings,DestFile,ExtractFilePath(SouDir));<br>&nbsp; finally<br>&nbsp; &nbsp; FileList.Free;<br>&nbsp; end;<br>end;<br><br><br>还有 <br><br>File_LoadString 函数,能不能也帮我帖一下。
 
对了,还有<br><br>procedure DeCompress1(CompressFile,DestPath:string);<br><br>中的 spCurrent 变量是什么时候定义的呢?<br><br>
 
procedure FindDir(DirName:string;var DirList:TStrings);<br>var DS:TSearchRec;<br>&nbsp; i,jd:integer;<br>&nbsp; s:string;<br>begin<br>&nbsp; i:=0;<br>&nbsp; DirList.Clear;<br>&nbsp; DirList.Add(DirName);<br>&nbsp; while i&lt;DirList.Count do<br>&nbsp; begin<br>&nbsp; &nbsp; s:=DirList.Strings;<br>&nbsp; &nbsp; if RightStr(s,1)&lt;&gt;'/' then s:=s+'/';<br>&nbsp; &nbsp; if FindFirst(s+'*.*',faAnyFile,Ds) = 0 then<br>&nbsp; &nbsp; &nbsp; repeat<br>&nbsp; &nbsp; &nbsp; &nbsp; if ((Ds.Attr and faDirectory)&lt;&gt;0) and (Ds.Name[1]&lt;&gt;'.') &nbsp;then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DirList.Add(s+Ds.Name);<br>&nbsp; &nbsp; &nbsp; until FindNext(Ds) &lt;&gt; 0;<br>&nbsp; &nbsp; Inc(i);<br>&nbsp; end;<br>&nbsp; FindClose(Ds);<br>end;<br><br><br>procedure FindFile(FileName:String;SubDir,AbsPath:Boolean;FileAttrs:integer; var FileNames:TStrings); //搜索指定目录<br>var Sr : TSearchRec;<br>&nbsp; &nbsp; Err,i,PathLen: integer;<br>&nbsp; &nbsp; kzh,s:string;<br>&nbsp; &nbsp; DirList:TStrings;<br>&nbsp; &nbsp; Path,FileType:string;<br>Begin<br>&nbsp; DirList:=Tstringlist.Create;<br>&nbsp; FileNames.Clear;<br>&nbsp; path:=ExtractFilePath(FileName);<br>&nbsp; PathLen:=Length(Path);<br>&nbsp; FileType:=ExtractFileName(FileName);<br>&nbsp; try<br>&nbsp; &nbsp; if SubDir then<br>&nbsp; &nbsp; &nbsp; FindDir(Path,DirList)<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; DirList.Add(Path);<br><br>&nbsp; &nbsp; for i:=0 to DirList.Count-1 do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; s:=DirList.Strings;<br>&nbsp; &nbsp; &nbsp; if RightStr(s,1)&lt;&gt;'/' then s:=s+'/';<br>&nbsp; &nbsp; &nbsp; Err:=FindFirst(s+FileType,FileAttrs,Sr);<br>&nbsp; &nbsp; &nbsp; While (Err = 0) do<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; if ((sr.Attr and FileAttrs) = sr.Attr) and (Sr.Name[1]&lt;&gt;'.') then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if AbsPath then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FileNames.Add(s+Sr.Name)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FileNames.Add(copy(s+Sr.Name,PathLen+1,1000));<br>&nbsp; &nbsp; &nbsp; &nbsp; Err:=FindNext(Sr) ;<br>&nbsp; &nbsp; &nbsp; end ;<br>&nbsp; &nbsp; end;<br>&nbsp; finally<br>&nbsp; &nbsp; FindClose(Sr);<br>&nbsp; &nbsp; DirList.Free;<br>&nbsp; end;<br>end;<br><br>function File_LoadString(iFileHandle,iFileSize:integer;var Str:String):Boolean;<br>var<br>&nbsp; FilePos,RecLen:LongWord;<br>begin<br>&nbsp; FilePos:=FileSeek(iFileHandle,0,1); &nbsp;//保存文件当前指针位置<br><br>&nbsp; Result:=(FilePos &lt; iFileSize) and (FileRead(iFileHandle, RecLen, SizeOf(RecLen))&gt;-1);<br>&nbsp; if Result then begin<br>&nbsp; &nbsp; SetLength(Str, RecLen);<br>&nbsp; &nbsp; Result:=(FilePos &lt; iFileSize) and (FileRead(iFileHandle, Str[1], RecLen)&gt;-1);<br>&nbsp; end;<br>&nbsp; if Result=False then<br>&nbsp; &nbsp; FileSeek(iFileHandle,FilePos,0);<br>end;<br><br><br>&nbsp;spCurrent 变量改为 1 即可
 
后退
顶部