流文件合并,线程处理。

unit Merger;

{***********************************************************************

                           流文件合并单元

        主要是使用线程进行流文件的合并处理。

        写作的目的在于之前有编文件使用批处理来进行TS文件的合并,效率
        很低,当时试了一下480M的TS需要合并半个多小时。因此自己忍不住
        写了个合并工具。
        这是工具的一部分代码。

        注:该单元请忽使用局部变量来执行,因为内嵌了线程,中间没有阻塞
        操作。因此局部变量,在执行后马上得到FREE。导致线程执行时异常。

        当然也可以进行改正到线程中的处理。后续读者自行处理吧。


        作者:边缘
        @RightCopy fsh
        QQ: 19985430
        Email:[email protected]
***********************************************************************}

interface

uses
    Classes,Windows,Sysutils;

    type
      TMerger = Class;

      TProcessThread = Class(TThread)
        private
          mgr:TMerger;
        protected
          constructor Create(instrance:TMerger);
          procedure Execute;override;
        public
      end;

      //处理进程进度事件
      TProcessEvent = procedure (Sender:TObject;curCount,Tatol:Integer) of Object;
      //处理完成后事件,单位为byte
      TProcessCompletedEvent = procedure (Sender:TObject;totalSize:Int64) of Object;
      //在进行停止操作前事件
      TProcessWillStopEvent = procedure (Sender:TObject;var is_stop:Boolean) of Object;

      TProcessState = (psNone,psProcessing,psPause,psStop,psCompleted);

      TMerger = Class
        private
          flist:TStringList;
          FpathName : String;
          Fprocess:TProcessEvent;
          FprocessCompleted:TProcessCompletedEvent;
          tranSize:Int64;
          FcCount:Integer;
          FtCount:Integer;
          FpState:TProcessState;
          FpThread:TprocessThread;
          FprocessStop:TProcessWillStopEvent;
          procedure initCache;
          procedure processMerger;
          procedure DeleteExistsFile;
          procedure DoProcess;
          procedure DoProcessCompleted;
          procedure ThreadProcess;
        public
          constructor Create;
          destructor Destroy;override;
          procedure MergerFileList(Const str:TStringList);
          procedure Pause;
          procedure resem;
          procedure Stop;
          procedure Start;
          procedure reStart;
          property savePathName:String read FpathName write FpathName;
          property processState:TProcessState read FpState;
          property OnProcess:TProcessEvent read Fprocess write Fprocess;
          property OnProcessCompleted:TProcessCompletedEvent read FprocessCompleted
                    write FprocessCompleted;
          property OnProcessWillStop:TProcessWillStopEvent read FprocessStop
                    write FprocessStop;
      End;
implementation

{ TMerger }

constructor TMerger.Create;
begin
   flist:=TStringList.Create;
   FpathName:=emptyStr;
   initCache;
end;

procedure TMerger.DeleteExistsFile;
begin
   if FileExists(FpathName) then DeleteFile(FpathName);
end;

destructor TMerger.Destroy;
begin
   flist.free;
  inherited;
end;

procedure TMerger.DoProcess;
begin
   if Assigned(Fprocess) then
      Fprocess(self,FcCount+1,FtCount);
end;

procedure TMerger.DoProcessCompleted;
begin
   if Assigned(FprocessCompleted) then
      FprocessCompleted(self,tranSize);
end;

procedure TMerger.initCache;
begin
   tranSize := 0;
   FcCount := 0;
   FtCount :=0;
   FpState := psNone;
end;

procedure TMerger.MergerFileList(const str: TStringList);
begin
   flist.Assign(str);
end;

procedure TMerger.Pause;
begin
   FpState := psPause;
end;

procedure TMerger.processMerger;
var
   fileItem:String;
   i:integer;
   Load:TFileStream;
   Save:TFileStream;
begin
   FtCount := flist.Count;

   if FileExists(FpathName) then
   begin
      Save := TFileStream.Create(FpathName, FmOpenWrite or fmShareDenyNone);
      Save.Position := Save.Size;
   end
   else
   begin
      Save := TFileStream.Create(FpathName,fmCreate or fmOpenReadWrite or fmShareDenyNone);
      Save.Position := 0;
   end;
   try
       for i := FcCount to FtCount - 1 do
       begin
           fileItem := flist[i];
           if FileExists(fileItem) then
           begin
             Load:=TFileStream.Create(fileItem,fmOpenRead);
             try
                Load.Position := 0;
                Save.CopyFrom(Load,Load.Size);
                tranSize := Save.Size;
                FcCount := I;
                FpThread.Synchronize(DoProcess);
             finally
                Load.Free;
             end;
           end;

           if (FpState = psPause) or (FpState = psStop) then break;
       end;

   finally
     Save.Free;
   end;

   if not ((FpState = psPause) or (FpState = psStop)) then
      FpThread.Synchronize(DoProcessCompleted);
end;

procedure TMerger.resem;
begin
   FpState := psProcessing;
   inc(FcCount);
   ThreadProcess;
end;

procedure TMerger.reStart;
begin
   Start;
end;

procedure TMerger.Start;
begin
   if FpathName = EmptyStr then Exit;

   initCache;
   
   DeleteExistsFile;

   //使用线程
   ThreadProcess;

   FpState := psProcessing;
end;

procedure TMerger.Stop;
var
   stp:Boolean;
begin
   Pause;
   stp := true;

   if Assigned(FprocessStop) then
      FprocessStop(self,stp);

   if stp then
      FpState := psStop
   else
      resem;
end;

procedure TMerger.ThreadProcess;
begin
   FpThread := TprocessThread.Create(self);
   FpThread.FreeOnTerminate := True;
end;

{ TProcessThread }

constructor TProcessThread.Create(instrance: TMerger);
begin
   mgr := instrance;
   inherited Create(false);
end;

procedure TProcessThread.Execute;
begin
   mgr.processMerger;
end;

end.

你可能感兴趣的:(Delphi)