如何实现从服务器下载文件到客户端啊

时间:2021-09-06 17:51:09
如何实现从服务器下载文件到客户端啊,三层的,soctet连接方式

11 个解决方案

#1



提交申请,将服务器文件保存到数据库中,
再从数据库内读取文件保存到本地

使用FTP服务
使用WinSocket

#2


创建一个连接,接收数据就可以了

#3


有例 子吗,有人能提供一个吗,谢谢

#4


帮你再顶起来

#5


有人能提供一个例子吗,谢谢

#6


有人能提供一个例子吗,谢谢

#7


我有
unit DownLoadThreadUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent,  IdFTP, StdCtrls, IdTCPConnection,
  IdTCPClient ,IdFTPList, ComCtrls ,IniFiles,  ExtCtrls,PubUnit,TypeUnit,ADODB;

type
  DownLoadThread = class(TThread)
  pbDownLoadFile: TProgressBar;
   idFtpClient: TIdFTP;
    btnFinish: TButton;        
    IsTransferring : Boolean;   //是否正在传送文件
    LocalPath: string;          //当前本地路径
    RemotePath: string;         //当前服务器路径
    RemoteFilesList:TStringList;
    LocalFilesList:TStringList;
    ftpServiceIP: string; //服务器IP地址
    port:Integer;
    user:string;
    pwd:string;
    version:Real;
    needUpdate:Boolean;
    m_lstOTConfig: TList;
    
    {读取ftp配置信息}
    function InitServer():Boolean;
     {连接ftp}
    function ConnectToServer(serverIp:string;serverPort:Integer;userName:string;pwd:string):Boolean;
      {关闭ftp连接}
    function CloseServerConnection():Boolean;
    
    {根据文件名下载文件}
    function DonwLoadFile(fileName:string):Boolean;

    {下载所有文件,当本地无任何展示文件或Access数据库记录数为0或Access数据库不存在时使用}
    function DonwLoadAllFiles():Integer;

     {检查Access连接}
    function CheckAccessConnection():Boolean;

    {检查本地文件是否健全,不健全则重新下载,0为成功}
    function CheckLoalFile():Integer;

    {更新文件,使本地文件配置与服务器同步}
    function UpdateFiles():Boolean;

    {初始化本地Access数据库信息,当本地无任何展示文件或Access数据库记录数为0时使用}
    function  InitAccessData():Boolean;

     {获取ftp当前目录下的文件}
    function DisplayRemoteFileList():TStringList;
    
    {获取本地目录的文件}
    function DisplayLocalFileList():TStringList;
    {清除无用的旧文件}
    function DeleteOldFiles():Boolean;
    {更新业务类型信息}
    function UpdateOperationTypeInfor():Boolean;    
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

implementation

uses ShowSaleInfoUnit, DoubleScreenUnit;

#8


{更新业务类型信息}
function DownLoadThread.UpdateOperationTypeInfor():Boolean;
var
  m_list:TList;
  operatetype:POperationtypeAll;
  i:Integer;
begin
  Result:=True;
  if not CheckAccessConnection  then
  begin
     Result:=false;
     exit;
  end;
  try
     GetOperationTypeAll(m_list);
     if (m_list =nil) or (m_list.Count<=0 )then
      begin
        Result:=false;
        Exit;
      end;  
  except
  end;
  with g_DataM.qryAccess do
  begin
    try
      if Active then
          Close;
        Sql.Clear;
        Sql.Add('delete FROM ZNYXFW_OPERATIONTYPE ');
        ExecSQL;

        for i:=0 to m_list.Count -1 do
        begin
          operatetype:=m_list.Items[i];
          try
            if Active then
             Close;
            Sql.Clear;
            Sql.Add('insert into  ZNYXFW_OPERATIONTYPE(OTNO,OTNAME,COMMENTS,GRADE,DSPCOUNT) values (@OTNO,@OTNAME,@COMMENTS,@GRADE,@DSPCOUNT) ');
            Parameters.ParamByName('@OTNO').Value := operatetype.OTNO;//.autoID;
            Parameters.ParamByName('@OTNAME').Value := operatetype.OTNAME;
            Parameters.ParamByName('@COMMENTS').Value := operatetype.COMMENTS;
            Parameters.ParamByName('@GRADE').Value := operatetype.GRADE;
            Parameters.ParamByName('@DSPCOUNT').Value := operatetype.DSPCOUNT;
            ExecSQL;
          except
          end;
        end;  
    except
    end;
  end;
end;
{检查Access连接}
function DownLoadThread.CheckAccessConnection():Boolean;
begin
   Result:=True;
   if g_DataM.adoAccess.Connected = false then
     begin
     try
      g_DataM.adoAccess.Connected := true;
      Result:=True;
     except
      g_DataM.adoAccess.Connected := false;
      Result:=False;  
     end;
   end;
end;

{
 检查本地文件是否健全,不健全则重新下载
 返回值:0为成功,1为部分文件下载失败,2为本地文件为空,3为连接Access失败,4为本地Access记录为空
}
function DownLoadThread.CheckLoalFile():integer;
var  
  fileName:string;
begin
    Result:=0;
    if (LocalFilesList=nil) or ( LocalFilesList.Count<=0 )then
    begin
       Result:=2;
       Exit;
    end;

    if not CheckAccessConnection()  then
    begin
       Result:=3;
       ShowMessage('本地配置文件错误,将无法正确更新展示信息!');
       Exit;
    end;
   

    with g_DataM.qryAccess do
    begin
      try
        if Active then
          Close;
        Sql.Clear;
        Sql.Add('SELECT * FROM OTConfig ');
        Active := true;
        if RecordCount <=0 then
        begin
          Result:=4;
          exit;
        end
        else
        begin
          while  (not Eof) do
           begin
             fileName:=  FieldByName('DSPFILENAME').AsString;
             if LocalFilesList.IndexOf(filename)<0  then
               if not DonwLoadFile(fileName) then
                 Result:=1;
             Next;
           end;
        end;
      except
      end;
    end;      
end;

{更新文件,使本地文件配置与服务器同步}
function DownLoadThread.UpdateFiles():Boolean;
var filename :string;
    i:Integer;
    tempPOT:POTConfigAllInfo;
    updateTime:TDateTime;
    tempOTNo:Integer;
    total:Integer;
    barposition:Integer;
begin
  Result:=False;
  GetAllOTConfigInfor(m_lstOTConfig);   //取服务器所有文件配置
  if (m_lstOTConfig=nil) or (m_lstOTConfig.Count<=0) then
    Exit ;

     //连接Access
  if not CheckAccessConnection  then
  begin
       ShowMessage('连接本地Access失败!');
       DonwLoadAllFiles(); 
       Exit;
  end;
    //读Access信息
   total:= m_lstOTConfig.Count;

   for i:=0 to (total -1) do
   begin
     barposition:=i*100 div total;
     pbDownLoadFile.Position:=barposition;
     
     tempPOT:=m_lstOTConfig.Items[i];
     with g_DataM.qryAccess do
      begin
        try
         if Active then
           Close;
         Sql.Clear;
         Sql.Add('SELECT * FROM OTConfig where AutoID=@autoID');
         Parameters.ParamByName('@autoID').Value := tempPOT.autoID;
         Active := true;
        except
        end;

        if RecordCount <=0 then //添加新文件
        begin
          try
           fileName:= tempPOT.szDspFileName;// FieldByName('DSPFILENAME').AsString;
           DonwLoadFile(fileName);
           if Active then
            Close;
           Sql.Clear;
           Sql.Add('insert into OTConfig(AutoID,OTNo,DSPFILENAME,DSPFILETYPE,COMMENTS,UpdateTime)  values (@autoID,@OTNo,@DSPFILENAME,@DSPFILETYPE,@COMMENTS,@UpdateTime)');
           Parameters.ParamByName('@AutoID').Value := tempPOT.autoID;
           Parameters.ParamByName('@OTNo').Value := tempPOT.nOtNo;
           Parameters.ParamByName('@DSPFILENAME').Value := tempPOT.szDspFileName;
           Parameters.ParamByName('@DSPFILETYPE').Value := tempPOT.nDspFileType;
           Parameters.ParamByName('@COMMENTS').Value := tempPOT.szComments;
           Parameters.ParamByName('@UpdateTime').Value := tempPOT.updateTime;
           ExecSQL;
          except
          end;
        end
        else   //修改旧文件
        begin
           tempOTNo:=FieldByName('OTNo').AsInteger;
           fileName:=  FieldByName('DSPFILENAME').AsString;
           updateTime:=FieldByName('UpdateTime').AsDateTime;
           if (filename <> tempPOT.szDspFileName) or(tempOTNo<>tempPOT.nOtNo) or(updateTime <>tempPOT.updateTime )   then
           begin
             try
               if FileExists(LocalPath+'\'+fileName) then
                  DeleteFile(LocalPath+'\'+fileName);
               DonwLoadFile( tempPOT.szDspFileName);
               if Active then
                  Close;
               Sql.Clear;
               Sql.Add('update OTConfig set OTNo=@OTNo,DSPFILENAME=@DSPFILENAME,DSPFILETYPE=@DSPFILETYPE,COMMENTS=@COMMENTS,UpdateTime=@UpdateTime where AutoID=@AutoID');
               Parameters.ParamByName('@AutoID').Value := tempPOT.autoID;
               Parameters.ParamByName('@OTNo').Value := tempPOT.nOtNo;
               Parameters.ParamByName('@DSPFILENAME').Value := tempPOT.szDspFileName;
               Parameters.ParamByName('@DSPFILETYPE').Value := tempPOT.nDspFileType;
               Parameters.ParamByName('@COMMENTS').Value := tempPOT.szComments;
               Parameters.ParamByName('@UpdateTime').Value := tempPOT.updateTime;
               ExecSQL;
             except
             end;
           end
           else
            Continue;
        end;
      end;
    end;
     barposition:=(total)*100 div total;
     pbDownLoadFile.Position:=barposition;   
end;

{
  下载所有文件,当Access数据库不存在或数据库记录为0时使用
   返回值0为成功,1为部分文件下载失败 ,2下载失败
}
function DownLoadThread.DonwLoadAllFiles():Integer;
var
    total:Integer;
    barposition:Integer;
    i:Integer;
begin
  Result:=0;
  try
     RemoteFilesList:=DisplayRemoteFileList();
     total:=RemoteFilesList.Count;
     for i:=0 to RemoteFilesList.Count-1 do
     begin
       try
          barposition:= i*100 div total;
          pbDownLoadFile.Position:=barposition;
          if not DonwLoadFile(RemoteFilesList.Strings[i]) then
              Result:=1;  
       except
         Result:=1;     
       end;
     end;
     barposition:=(total)*100 div total;
     pbDownLoadFile.Position:=barposition;
  except
    Result:=2;
  end;
end;

#9


{初始化本地Access数据库信息,当本地无任何展示文件或Access数据库记录数为0时使用}
function  DownLoadThread.InitAccessData():Boolean;
var
  i:Integer;
  tempPOT:POTConfigAllInfo;
  total:Integer;
begin
  //连接Access
  if not CheckAccessConnection  then
  begin
       ShowMessage('连接Access失败!');
       Result:=False;
       Exit;
  end;
  GetAllOTConfigInfor(m_lstOTConfig);   //取服务器所有文件配置
  if (m_lstOTConfig=nil) or (m_lstOTConfig.Count<=0) then
  begin
    Result:=false;
    Exit ;
  end;
  
  Result:=True;
  total:=m_lstOTConfig.Count;
  if total<=0 then
     Exit;
  //清空Access数据库   
  try
     with g_DataM.qryAccess do
     begin
           if Active then
           Close;
           Sql.Clear;
           Sql.Add('delete from OTConfig');  
           ExecSQL;
           //Active := true;
     end;
  except    
  end;

  for i:=0 to (total-1) do
  begin
    tempPOT:=m_lstOTConfig.Items[i];
    try
     with g_DataM.qryAccess do
     begin
           if Active then
           Close;
           Sql.Clear;
           Sql.Add('insert into OTConfig(AutoID,OTNo,DSPFILENAME,DSPFILETYPE,COMMENTS,UpdateTime)  values (@autoID,@OTNo,@DSPFILENAME,@DSPFILETYPE,@COMMENTS,@UpdateTime)');
           Parameters.ParamByName('@AutoID').Value := tempPOT.autoID;
           Parameters.ParamByName('@OTNo').Value := tempPOT.nOtNo;
           Parameters.ParamByName('@DSPFILENAME').Value := tempPOT.szDspFileName;
           Parameters.ParamByName('@DSPFILETYPE').Value := tempPOT.nDspFileType;
           Parameters.ParamByName('@COMMENTS').Value := tempPOT.szComments;
           Parameters.ParamByName('@UpdateTime').Value := tempPOT.updateTime;
           ExecSQL;// Active := true;
     end;
    except
       Result:=false;
    end;
  end;
end;
  {清除无用的旧文件}
function DownLoadThread.DeleteOldFiles():Boolean;
var
  strlist:TStringList;
  i:Integer;
  tempOT:POTConfigAllInfo;
  strAutoID:string;
begin
  Result:=false;
  if (m_lstOTConfig=nil) or (m_lstOTConfig.Count<=0) then
    Exit;

  strlist:=TStringList.Create;
  for i:=0 to  m_lstOTConfig.Count-1 do
  try
     tempOT:= m_lstOTConfig.Items[i];
     strlist.Add(IntToStr(tempot.autoID));
  except
  end;

  if not CheckAccessConnection then
    Exit;
  try
   with g_DataM.qryAccess do
   begin
           if Active then
           Close;
           Sql.Clear;
           Sql.Add('select * from OTConfig');
           Active := true;
           if RecordCount >0 then
            while  (not Eof) do
            begin
             strAutoID:=  FieldByName('AutoID').AsString;
             if strlist.IndexOf(strAutoID)<0  then
             begin
               try
               {删除文件}
               DeleteFile(LocalPath+'\'+FieldByName('DSPFILENAME').AsString);
              
                {删除数据库记录}
               if g_DataM.qryDeleteOld.Active then
                Close;
               g_DataM.qryDeleteOld.SQL.Clear;
               g_DataM.qryDeleteOld.SQL.Add('delete from OTConfig where AutoID=@AutoID');
               g_DataM.qryDeleteOld.Parameters.ParamByName('@AutoID').Value := FieldByName('AutoID').AsInteger;
               g_DataM.qryDeleteOld.ExecSQL;
               except
               end;
             end;
             Next;
            end; 
   end;
  except
  end;
  Result:=True;
end;
  {下载线程执行方法}
procedure DownLoadThread.Execute;
var
    oldpath:string;
    tempInt:Integer;
    bLoad :Boolean;
begin
     bLoad := False;
     try
      try
      begin
        oldpath:=SysUtils.GetCurrentDir();
        RemotePath:='/';
        LocalPath:='C:\DSPFile';

        if not InitServer then
        begin
          ShowMessage('读取配置文件出错,系统退出 ! ');
        end;

        if(not ConnectToServer(ftpServiceIP,port,user,pwd))then
        begin
            ShowMessage('连接服务器失败');
            Exit;
        end;

        if not CheckAccessConnection then
        begin
           DonwLoadAllFiles;
           Exit;
        end;
        UpdateOperationTypeInfor;
        LocalFilesList:=DisplayLocalFileList();
        tempInt:=CheckLoalFile;
        if  (tempInt=0)  or (tempInt=1) then
          UpdateFiles()
        else if  (tempInt=2) or (tempInt=4) or(tempInt=3) then
        begin
           DonwLoadAllFiles();
           if  (tempInt=2) or (tempInt=4) then
               InitAccessData();
        end;
        DeleteOldFiles();
        SysUtils.SetCurrentDir(oldpath);
     end
     except
        ShowMessage('文件更新失败');
     end;
    finally
        btnFinish.Enabled:=True;
        btnFinish.Visible:=True;
    end;
    //如果原来已经打开过,则现在重新打开
    if(Assigned(SaleInfoShowFrm)) then
      bLoad := SaleInfoShowFrm.bIsLoadDoubleScreen;
    if(bLoad) then
    begin
      if(Screen.MonitorCount > 1) then
      begin
        SaleInfoShowFrm.bIsLoadDoubleScreen := True;
        Application.CreateForm(TfrmDoubleScreen, frmDoubleScreen);
        if(Screen.Monitors[0].Primary) then
        begin
          frmDoubleScreen.ShowForm(Screen.Monitors[1]);
        end
        else
        begin
          frmDoubleScreen.ShowForm(Screen.Monitors[0]);
        end;
        //frmDoubleScreen.Setdefa
      end;
  end;
end;


{读取ftp配置信息,初始化失败直接退出}
function DownLoadThread.InitServer():Boolean;
var
  lstSvrIP: TStringList;  //服务器IP地址列表
  versionList:TStringList;
  Ini: TIniFile;  //系统配置文件
  nPos: integer;  //取服务器IP的临时变量
begin
    Result:=True;
    try
      begin
         lstSvrIP := TStringList.Create;
         versionList:= TStringList.Create;
         Ini := TIniFile.Create(GetCurrentDir+'\config.ini');
         Ini.ReadSectionValues('FtpServer', lstSvrIP);
         Ini.ReadSectionValues('FileVersion', versionList);
         Ini.Destroy;
         
         nPos := pos('=',lstSvrIP.Strings[0]);
         ftpServiceIP := Trim(copy(lstSvrIP.Strings[0], nPos + 1, length(lstSvrIP.Strings[0]) - nPos));
         nPos := pos('=',lstSvrIP.Strings[1]);
         port:=StrToInt( Trim(copy(lstSvrIP.Strings[1], nPos + 1, length(lstSvrIP.Strings[1]) - nPos)));
         nPos := pos('=',lstSvrIP.Strings[2]);
         user:=Trim(copy(lstSvrIP.Strings[2], nPos + 1, length(lstSvrIP.Strings[2]) - nPos));
         nPos := pos('=',lstSvrIP.Strings[3]);
         pwd:=Trim(copy(lstSvrIP.Strings[3], nPos + 1, length(lstSvrIP.Strings[3]) - nPos));
         nPos := pos('=',versionList.Strings[0]);
         Self.version := StrToFloat((copy(versionList.Strings[0], nPos + 1, length(versionList.Strings[0]) - nPos)));
      end;
    except
      on E: exception do
      begin
        Result:=false;
      end;
    end;
end;


  {连接ftp}
 function DownLoadThread.ConnectToServer(serverIp:string;serverPort:Integer;userName:string;pwd:string):Boolean;
 var i:Integer;
 begin
 
    RemotePath:='/';
    Result:=False;
    if idFtpClient.Connected then  //已经建立了连接吗?
    begin
         Result:=True;
         exit;  //退出本函数
    end;

    try
     //连接服务器属性设置
     idFtpClient.Host:=serverIp;//'202.119.205.159';
     idFtpClient.Port:=serverPort;//StrToInt(serverPort);//'2121');
     idFtpClient.UserName:=userName;//'huqifei';
     idFtpClient.Password:=pwd;//'1';
     i:=0;
     while (i < 3)  do    //自动重连,重连3次
      begin
        idFtpClient.Connect;
        if(idFtpClient.Connected) then
        begin
          Result:=True;
          Exit;
        end;
        i:=i+1;
      end; 
   except
     Result:=False;
   end;

 end;

    
 

#10


    {根据文件名下载文件}
function DownLoadThread.DonwLoadFile(fileName:string):Boolean;
begin
      Result:=False;
      try
        begin
          SetCurrentDir(LocalPath);
          if( not DirectoryExists(LocalPath)) then
            CreateDir(LocalPath);
          if FileExists(fileName) then   //判断文件是否存在
          begin
           idFtpClient.Get(FileName, LocalPath+'\'+FileName,false, true)  //续传
          //  idFtpClient.Get(FileName, LocalPath+'\'+FileName, true,False);  //覆盖
          end
          else
            idFtpClient.Get(FileName, LocalPath+'\'+FileName, false);      //下载
          Result:=true;
         end
       except
          Result:=False;
       end
     // Self.LocalFilesList:=Self.DisplayLocalFileList;      //刷新本地文件列表


end;

    {关闭ftp连接}
function DownLoadThread.CloseServerConnection():Boolean;
    begin
     try
     begin
      Self.idFtpClient.Abort;
      if idFtpClient.Connected=False    then
            Result:=True
      else
            Result:=False;
     end
     except 
         Result:=False;
     end;

end;
function DownLoadThread.DisplayRemoteFileList():TStringList;
Var
  LS: TStringList;
  FileList:TStringList;
  FileCount: Integer;
  //newItem : TListItem;
begin
  LS := TStringList.Create;
  FileList:=TStringList.Create;
  try
    idFtpClient.ChangeDir(RemotePath);  //设置FTP服务器当前目录
    idFtpClient.List(LS);    //得到文件和目录列表  
    //处理LS的每个项目
    for FileCount:=0 to LS.Count - 1 do
    begin
      //是文件吗?
      if idFtpClient.DirectoryListing.Items[FileCount].ItemType=IdFTPList.ditFile then
      begin
        FileList.Add( idFtpClient.DirectoryListing.Items[FileCount].FileName);
      end;
      
   end;
  finally
    Result:=FileList;
    LS.Free;   //释放TStringList
  end;
end;

//显示本地文件列表
function DownLoadThread.DisplayLocalFileList():TStringList;
var
  sr: TSearchRec;
  LS:TStringList;

begin
  LS:=TStringList.Create;
  SetCurrentDir(LocalPath);  //设置当前路径
  //填加文件
  if FindFirst('*',  faArchive, sr) = 0 then
  begin
    repeat
      LS.Add(sr.Name);
     { Item:=ListViewLocalFile.Items.Add;
      Item.ImageIndex:=1;      //图标序号
      Item.Caption:=sr.Name;  //文件名
      Item.SubItems.Add('');
      Item.SubItems.Add(IntToStr(sr.Size));  //文件大小
      Item.SubItems.Add(DateTimeToStr(FileDateToDateTime(sr.Time)));  //时间
      }
    until FindNext(sr) <> 0;    //下一个
    FindClose(sr);  //结束查找
  end;
  if LS.Count>0 then
  Result:=LS
  else
  Result:=nil;
end;
end.

#11


这个代码的实现和你的要求一直,通过3层结构到服务器上检索是否有新的文件
如果有,删除本地文件,下载新文件

#1



提交申请,将服务器文件保存到数据库中,
再从数据库内读取文件保存到本地

使用FTP服务
使用WinSocket

#2


创建一个连接,接收数据就可以了

#3


有例 子吗,有人能提供一个吗,谢谢

#4


帮你再顶起来

#5


有人能提供一个例子吗,谢谢

#6


有人能提供一个例子吗,谢谢

#7


我有
unit DownLoadThreadUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent,  IdFTP, StdCtrls, IdTCPConnection,
  IdTCPClient ,IdFTPList, ComCtrls ,IniFiles,  ExtCtrls,PubUnit,TypeUnit,ADODB;

type
  DownLoadThread = class(TThread)
  pbDownLoadFile: TProgressBar;
   idFtpClient: TIdFTP;
    btnFinish: TButton;        
    IsTransferring : Boolean;   //是否正在传送文件
    LocalPath: string;          //当前本地路径
    RemotePath: string;         //当前服务器路径
    RemoteFilesList:TStringList;
    LocalFilesList:TStringList;
    ftpServiceIP: string; //服务器IP地址
    port:Integer;
    user:string;
    pwd:string;
    version:Real;
    needUpdate:Boolean;
    m_lstOTConfig: TList;
    
    {读取ftp配置信息}
    function InitServer():Boolean;
     {连接ftp}
    function ConnectToServer(serverIp:string;serverPort:Integer;userName:string;pwd:string):Boolean;
      {关闭ftp连接}
    function CloseServerConnection():Boolean;
    
    {根据文件名下载文件}
    function DonwLoadFile(fileName:string):Boolean;

    {下载所有文件,当本地无任何展示文件或Access数据库记录数为0或Access数据库不存在时使用}
    function DonwLoadAllFiles():Integer;

     {检查Access连接}
    function CheckAccessConnection():Boolean;

    {检查本地文件是否健全,不健全则重新下载,0为成功}
    function CheckLoalFile():Integer;

    {更新文件,使本地文件配置与服务器同步}
    function UpdateFiles():Boolean;

    {初始化本地Access数据库信息,当本地无任何展示文件或Access数据库记录数为0时使用}
    function  InitAccessData():Boolean;

     {获取ftp当前目录下的文件}
    function DisplayRemoteFileList():TStringList;
    
    {获取本地目录的文件}
    function DisplayLocalFileList():TStringList;
    {清除无用的旧文件}
    function DeleteOldFiles():Boolean;
    {更新业务类型信息}
    function UpdateOperationTypeInfor():Boolean;    
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

implementation

uses ShowSaleInfoUnit, DoubleScreenUnit;

#8


{更新业务类型信息}
function DownLoadThread.UpdateOperationTypeInfor():Boolean;
var
  m_list:TList;
  operatetype:POperationtypeAll;
  i:Integer;
begin
  Result:=True;
  if not CheckAccessConnection  then
  begin
     Result:=false;
     exit;
  end;
  try
     GetOperationTypeAll(m_list);
     if (m_list =nil) or (m_list.Count<=0 )then
      begin
        Result:=false;
        Exit;
      end;  
  except
  end;
  with g_DataM.qryAccess do
  begin
    try
      if Active then
          Close;
        Sql.Clear;
        Sql.Add('delete FROM ZNYXFW_OPERATIONTYPE ');
        ExecSQL;

        for i:=0 to m_list.Count -1 do
        begin
          operatetype:=m_list.Items[i];
          try
            if Active then
             Close;
            Sql.Clear;
            Sql.Add('insert into  ZNYXFW_OPERATIONTYPE(OTNO,OTNAME,COMMENTS,GRADE,DSPCOUNT) values (@OTNO,@OTNAME,@COMMENTS,@GRADE,@DSPCOUNT) ');
            Parameters.ParamByName('@OTNO').Value := operatetype.OTNO;//.autoID;
            Parameters.ParamByName('@OTNAME').Value := operatetype.OTNAME;
            Parameters.ParamByName('@COMMENTS').Value := operatetype.COMMENTS;
            Parameters.ParamByName('@GRADE').Value := operatetype.GRADE;
            Parameters.ParamByName('@DSPCOUNT').Value := operatetype.DSPCOUNT;
            ExecSQL;
          except
          end;
        end;  
    except
    end;
  end;
end;
{检查Access连接}
function DownLoadThread.CheckAccessConnection():Boolean;
begin
   Result:=True;
   if g_DataM.adoAccess.Connected = false then
     begin
     try
      g_DataM.adoAccess.Connected := true;
      Result:=True;
     except
      g_DataM.adoAccess.Connected := false;
      Result:=False;  
     end;
   end;
end;

{
 检查本地文件是否健全,不健全则重新下载
 返回值:0为成功,1为部分文件下载失败,2为本地文件为空,3为连接Access失败,4为本地Access记录为空
}
function DownLoadThread.CheckLoalFile():integer;
var  
  fileName:string;
begin
    Result:=0;
    if (LocalFilesList=nil) or ( LocalFilesList.Count<=0 )then
    begin
       Result:=2;
       Exit;
    end;

    if not CheckAccessConnection()  then
    begin
       Result:=3;
       ShowMessage('本地配置文件错误,将无法正确更新展示信息!');
       Exit;
    end;
   

    with g_DataM.qryAccess do
    begin
      try
        if Active then
          Close;
        Sql.Clear;
        Sql.Add('SELECT * FROM OTConfig ');
        Active := true;
        if RecordCount <=0 then
        begin
          Result:=4;
          exit;
        end
        else
        begin
          while  (not Eof) do
           begin
             fileName:=  FieldByName('DSPFILENAME').AsString;
             if LocalFilesList.IndexOf(filename)<0  then
               if not DonwLoadFile(fileName) then
                 Result:=1;
             Next;
           end;
        end;
      except
      end;
    end;      
end;

{更新文件,使本地文件配置与服务器同步}
function DownLoadThread.UpdateFiles():Boolean;
var filename :string;
    i:Integer;
    tempPOT:POTConfigAllInfo;
    updateTime:TDateTime;
    tempOTNo:Integer;
    total:Integer;
    barposition:Integer;
begin
  Result:=False;
  GetAllOTConfigInfor(m_lstOTConfig);   //取服务器所有文件配置
  if (m_lstOTConfig=nil) or (m_lstOTConfig.Count<=0) then
    Exit ;

     //连接Access
  if not CheckAccessConnection  then
  begin
       ShowMessage('连接本地Access失败!');
       DonwLoadAllFiles(); 
       Exit;
  end;
    //读Access信息
   total:= m_lstOTConfig.Count;

   for i:=0 to (total -1) do
   begin
     barposition:=i*100 div total;
     pbDownLoadFile.Position:=barposition;
     
     tempPOT:=m_lstOTConfig.Items[i];
     with g_DataM.qryAccess do
      begin
        try
         if Active then
           Close;
         Sql.Clear;
         Sql.Add('SELECT * FROM OTConfig where AutoID=@autoID');
         Parameters.ParamByName('@autoID').Value := tempPOT.autoID;
         Active := true;
        except
        end;

        if RecordCount <=0 then //添加新文件
        begin
          try
           fileName:= tempPOT.szDspFileName;// FieldByName('DSPFILENAME').AsString;
           DonwLoadFile(fileName);
           if Active then
            Close;
           Sql.Clear;
           Sql.Add('insert into OTConfig(AutoID,OTNo,DSPFILENAME,DSPFILETYPE,COMMENTS,UpdateTime)  values (@autoID,@OTNo,@DSPFILENAME,@DSPFILETYPE,@COMMENTS,@UpdateTime)');
           Parameters.ParamByName('@AutoID').Value := tempPOT.autoID;
           Parameters.ParamByName('@OTNo').Value := tempPOT.nOtNo;
           Parameters.ParamByName('@DSPFILENAME').Value := tempPOT.szDspFileName;
           Parameters.ParamByName('@DSPFILETYPE').Value := tempPOT.nDspFileType;
           Parameters.ParamByName('@COMMENTS').Value := tempPOT.szComments;
           Parameters.ParamByName('@UpdateTime').Value := tempPOT.updateTime;
           ExecSQL;
          except
          end;
        end
        else   //修改旧文件
        begin
           tempOTNo:=FieldByName('OTNo').AsInteger;
           fileName:=  FieldByName('DSPFILENAME').AsString;
           updateTime:=FieldByName('UpdateTime').AsDateTime;
           if (filename <> tempPOT.szDspFileName) or(tempOTNo<>tempPOT.nOtNo) or(updateTime <>tempPOT.updateTime )   then
           begin
             try
               if FileExists(LocalPath+'\'+fileName) then
                  DeleteFile(LocalPath+'\'+fileName);
               DonwLoadFile( tempPOT.szDspFileName);
               if Active then
                  Close;
               Sql.Clear;
               Sql.Add('update OTConfig set OTNo=@OTNo,DSPFILENAME=@DSPFILENAME,DSPFILETYPE=@DSPFILETYPE,COMMENTS=@COMMENTS,UpdateTime=@UpdateTime where AutoID=@AutoID');
               Parameters.ParamByName('@AutoID').Value := tempPOT.autoID;
               Parameters.ParamByName('@OTNo').Value := tempPOT.nOtNo;
               Parameters.ParamByName('@DSPFILENAME').Value := tempPOT.szDspFileName;
               Parameters.ParamByName('@DSPFILETYPE').Value := tempPOT.nDspFileType;
               Parameters.ParamByName('@COMMENTS').Value := tempPOT.szComments;
               Parameters.ParamByName('@UpdateTime').Value := tempPOT.updateTime;
               ExecSQL;
             except
             end;
           end
           else
            Continue;
        end;
      end;
    end;
     barposition:=(total)*100 div total;
     pbDownLoadFile.Position:=barposition;   
end;

{
  下载所有文件,当Access数据库不存在或数据库记录为0时使用
   返回值0为成功,1为部分文件下载失败 ,2下载失败
}
function DownLoadThread.DonwLoadAllFiles():Integer;
var
    total:Integer;
    barposition:Integer;
    i:Integer;
begin
  Result:=0;
  try
     RemoteFilesList:=DisplayRemoteFileList();
     total:=RemoteFilesList.Count;
     for i:=0 to RemoteFilesList.Count-1 do
     begin
       try
          barposition:= i*100 div total;
          pbDownLoadFile.Position:=barposition;
          if not DonwLoadFile(RemoteFilesList.Strings[i]) then
              Result:=1;  
       except
         Result:=1;     
       end;
     end;
     barposition:=(total)*100 div total;
     pbDownLoadFile.Position:=barposition;
  except
    Result:=2;
  end;
end;

#9


{初始化本地Access数据库信息,当本地无任何展示文件或Access数据库记录数为0时使用}
function  DownLoadThread.InitAccessData():Boolean;
var
  i:Integer;
  tempPOT:POTConfigAllInfo;
  total:Integer;
begin
  //连接Access
  if not CheckAccessConnection  then
  begin
       ShowMessage('连接Access失败!');
       Result:=False;
       Exit;
  end;
  GetAllOTConfigInfor(m_lstOTConfig);   //取服务器所有文件配置
  if (m_lstOTConfig=nil) or (m_lstOTConfig.Count<=0) then
  begin
    Result:=false;
    Exit ;
  end;
  
  Result:=True;
  total:=m_lstOTConfig.Count;
  if total<=0 then
     Exit;
  //清空Access数据库   
  try
     with g_DataM.qryAccess do
     begin
           if Active then
           Close;
           Sql.Clear;
           Sql.Add('delete from OTConfig');  
           ExecSQL;
           //Active := true;
     end;
  except    
  end;

  for i:=0 to (total-1) do
  begin
    tempPOT:=m_lstOTConfig.Items[i];
    try
     with g_DataM.qryAccess do
     begin
           if Active then
           Close;
           Sql.Clear;
           Sql.Add('insert into OTConfig(AutoID,OTNo,DSPFILENAME,DSPFILETYPE,COMMENTS,UpdateTime)  values (@autoID,@OTNo,@DSPFILENAME,@DSPFILETYPE,@COMMENTS,@UpdateTime)');
           Parameters.ParamByName('@AutoID').Value := tempPOT.autoID;
           Parameters.ParamByName('@OTNo').Value := tempPOT.nOtNo;
           Parameters.ParamByName('@DSPFILENAME').Value := tempPOT.szDspFileName;
           Parameters.ParamByName('@DSPFILETYPE').Value := tempPOT.nDspFileType;
           Parameters.ParamByName('@COMMENTS').Value := tempPOT.szComments;
           Parameters.ParamByName('@UpdateTime').Value := tempPOT.updateTime;
           ExecSQL;// Active := true;
     end;
    except
       Result:=false;
    end;
  end;
end;
  {清除无用的旧文件}
function DownLoadThread.DeleteOldFiles():Boolean;
var
  strlist:TStringList;
  i:Integer;
  tempOT:POTConfigAllInfo;
  strAutoID:string;
begin
  Result:=false;
  if (m_lstOTConfig=nil) or (m_lstOTConfig.Count<=0) then
    Exit;

  strlist:=TStringList.Create;
  for i:=0 to  m_lstOTConfig.Count-1 do
  try
     tempOT:= m_lstOTConfig.Items[i];
     strlist.Add(IntToStr(tempot.autoID));
  except
  end;

  if not CheckAccessConnection then
    Exit;
  try
   with g_DataM.qryAccess do
   begin
           if Active then
           Close;
           Sql.Clear;
           Sql.Add('select * from OTConfig');
           Active := true;
           if RecordCount >0 then
            while  (not Eof) do
            begin
             strAutoID:=  FieldByName('AutoID').AsString;
             if strlist.IndexOf(strAutoID)<0  then
             begin
               try
               {删除文件}
               DeleteFile(LocalPath+'\'+FieldByName('DSPFILENAME').AsString);
              
                {删除数据库记录}
               if g_DataM.qryDeleteOld.Active then
                Close;
               g_DataM.qryDeleteOld.SQL.Clear;
               g_DataM.qryDeleteOld.SQL.Add('delete from OTConfig where AutoID=@AutoID');
               g_DataM.qryDeleteOld.Parameters.ParamByName('@AutoID').Value := FieldByName('AutoID').AsInteger;
               g_DataM.qryDeleteOld.ExecSQL;
               except
               end;
             end;
             Next;
            end; 
   end;
  except
  end;
  Result:=True;
end;
  {下载线程执行方法}
procedure DownLoadThread.Execute;
var
    oldpath:string;
    tempInt:Integer;
    bLoad :Boolean;
begin
     bLoad := False;
     try
      try
      begin
        oldpath:=SysUtils.GetCurrentDir();
        RemotePath:='/';
        LocalPath:='C:\DSPFile';

        if not InitServer then
        begin
          ShowMessage('读取配置文件出错,系统退出 ! ');
        end;

        if(not ConnectToServer(ftpServiceIP,port,user,pwd))then
        begin
            ShowMessage('连接服务器失败');
            Exit;
        end;

        if not CheckAccessConnection then
        begin
           DonwLoadAllFiles;
           Exit;
        end;
        UpdateOperationTypeInfor;
        LocalFilesList:=DisplayLocalFileList();
        tempInt:=CheckLoalFile;
        if  (tempInt=0)  or (tempInt=1) then
          UpdateFiles()
        else if  (tempInt=2) or (tempInt=4) or(tempInt=3) then
        begin
           DonwLoadAllFiles();
           if  (tempInt=2) or (tempInt=4) then
               InitAccessData();
        end;
        DeleteOldFiles();
        SysUtils.SetCurrentDir(oldpath);
     end
     except
        ShowMessage('文件更新失败');
     end;
    finally
        btnFinish.Enabled:=True;
        btnFinish.Visible:=True;
    end;
    //如果原来已经打开过,则现在重新打开
    if(Assigned(SaleInfoShowFrm)) then
      bLoad := SaleInfoShowFrm.bIsLoadDoubleScreen;
    if(bLoad) then
    begin
      if(Screen.MonitorCount > 1) then
      begin
        SaleInfoShowFrm.bIsLoadDoubleScreen := True;
        Application.CreateForm(TfrmDoubleScreen, frmDoubleScreen);
        if(Screen.Monitors[0].Primary) then
        begin
          frmDoubleScreen.ShowForm(Screen.Monitors[1]);
        end
        else
        begin
          frmDoubleScreen.ShowForm(Screen.Monitors[0]);
        end;
        //frmDoubleScreen.Setdefa
      end;
  end;
end;


{读取ftp配置信息,初始化失败直接退出}
function DownLoadThread.InitServer():Boolean;
var
  lstSvrIP: TStringList;  //服务器IP地址列表
  versionList:TStringList;
  Ini: TIniFile;  //系统配置文件
  nPos: integer;  //取服务器IP的临时变量
begin
    Result:=True;
    try
      begin
         lstSvrIP := TStringList.Create;
         versionList:= TStringList.Create;
         Ini := TIniFile.Create(GetCurrentDir+'\config.ini');
         Ini.ReadSectionValues('FtpServer', lstSvrIP);
         Ini.ReadSectionValues('FileVersion', versionList);
         Ini.Destroy;
         
         nPos := pos('=',lstSvrIP.Strings[0]);
         ftpServiceIP := Trim(copy(lstSvrIP.Strings[0], nPos + 1, length(lstSvrIP.Strings[0]) - nPos));
         nPos := pos('=',lstSvrIP.Strings[1]);
         port:=StrToInt( Trim(copy(lstSvrIP.Strings[1], nPos + 1, length(lstSvrIP.Strings[1]) - nPos)));
         nPos := pos('=',lstSvrIP.Strings[2]);
         user:=Trim(copy(lstSvrIP.Strings[2], nPos + 1, length(lstSvrIP.Strings[2]) - nPos));
         nPos := pos('=',lstSvrIP.Strings[3]);
         pwd:=Trim(copy(lstSvrIP.Strings[3], nPos + 1, length(lstSvrIP.Strings[3]) - nPos));
         nPos := pos('=',versionList.Strings[0]);
         Self.version := StrToFloat((copy(versionList.Strings[0], nPos + 1, length(versionList.Strings[0]) - nPos)));
      end;
    except
      on E: exception do
      begin
        Result:=false;
      end;
    end;
end;


  {连接ftp}
 function DownLoadThread.ConnectToServer(serverIp:string;serverPort:Integer;userName:string;pwd:string):Boolean;
 var i:Integer;
 begin
 
    RemotePath:='/';
    Result:=False;
    if idFtpClient.Connected then  //已经建立了连接吗?
    begin
         Result:=True;
         exit;  //退出本函数
    end;

    try
     //连接服务器属性设置
     idFtpClient.Host:=serverIp;//'202.119.205.159';
     idFtpClient.Port:=serverPort;//StrToInt(serverPort);//'2121');
     idFtpClient.UserName:=userName;//'huqifei';
     idFtpClient.Password:=pwd;//'1';
     i:=0;
     while (i < 3)  do    //自动重连,重连3次
      begin
        idFtpClient.Connect;
        if(idFtpClient.Connected) then
        begin
          Result:=True;
          Exit;
        end;
        i:=i+1;
      end; 
   except
     Result:=False;
   end;

 end;

    
 

#10


    {根据文件名下载文件}
function DownLoadThread.DonwLoadFile(fileName:string):Boolean;
begin
      Result:=False;
      try
        begin
          SetCurrentDir(LocalPath);
          if( not DirectoryExists(LocalPath)) then
            CreateDir(LocalPath);
          if FileExists(fileName) then   //判断文件是否存在
          begin
           idFtpClient.Get(FileName, LocalPath+'\'+FileName,false, true)  //续传
          //  idFtpClient.Get(FileName, LocalPath+'\'+FileName, true,False);  //覆盖
          end
          else
            idFtpClient.Get(FileName, LocalPath+'\'+FileName, false);      //下载
          Result:=true;
         end
       except
          Result:=False;
       end
     // Self.LocalFilesList:=Self.DisplayLocalFileList;      //刷新本地文件列表


end;

    {关闭ftp连接}
function DownLoadThread.CloseServerConnection():Boolean;
    begin
     try
     begin
      Self.idFtpClient.Abort;
      if idFtpClient.Connected=False    then
            Result:=True
      else
            Result:=False;
     end
     except 
         Result:=False;
     end;

end;
function DownLoadThread.DisplayRemoteFileList():TStringList;
Var
  LS: TStringList;
  FileList:TStringList;
  FileCount: Integer;
  //newItem : TListItem;
begin
  LS := TStringList.Create;
  FileList:=TStringList.Create;
  try
    idFtpClient.ChangeDir(RemotePath);  //设置FTP服务器当前目录
    idFtpClient.List(LS);    //得到文件和目录列表  
    //处理LS的每个项目
    for FileCount:=0 to LS.Count - 1 do
    begin
      //是文件吗?
      if idFtpClient.DirectoryListing.Items[FileCount].ItemType=IdFTPList.ditFile then
      begin
        FileList.Add( idFtpClient.DirectoryListing.Items[FileCount].FileName);
      end;
      
   end;
  finally
    Result:=FileList;
    LS.Free;   //释放TStringList
  end;
end;

//显示本地文件列表
function DownLoadThread.DisplayLocalFileList():TStringList;
var
  sr: TSearchRec;
  LS:TStringList;

begin
  LS:=TStringList.Create;
  SetCurrentDir(LocalPath);  //设置当前路径
  //填加文件
  if FindFirst('*',  faArchive, sr) = 0 then
  begin
    repeat
      LS.Add(sr.Name);
     { Item:=ListViewLocalFile.Items.Add;
      Item.ImageIndex:=1;      //图标序号
      Item.Caption:=sr.Name;  //文件名
      Item.SubItems.Add('');
      Item.SubItems.Add(IntToStr(sr.Size));  //文件大小
      Item.SubItems.Add(DateTimeToStr(FileDateToDateTime(sr.Time)));  //时间
      }
    until FindNext(sr) <> 0;    //下一个
    FindClose(sr);  //结束查找
  end;
  if LS.Count>0 then
  Result:=LS
  else
  Result:=nil;
end;
end.

#11


这个代码的实现和你的要求一直,通过3层结构到服务器上检索是否有新的文件
如果有,删除本地文件,下载新文件