zoukankan      html  css  js  c++  java
  • Delphi完成的断点续传例子 转

    unit Unit1;
    interface
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls, IdFTP, IdBaseComponent, IdComponent,
      IdTCPConnection, IdTCPClient, IdHTTP, IdHTTPHeaderInfo, ExtCtrls;
    type
      TForm1 = class(TForm)
        ListBox1: TListBox;
        Panel1: TPanel;
        Label1: TLabel;
        Label2: TLabel;
        Button1: TButton;
        ProgressBar1: TProgressBar;
        Button2: TButton;
        IdHTTP1: TIdHTTP;
        IdFTP1: TIdFTP;
        Button3: TButton;
        ComboBox1: TComboBox;
        procedure Button2Click(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure IdHTTP1Work(Sender: TObject; AWorkMode: TWorkMode;
          const AWorkCount: Integer);
        procedure IdHTTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
          const AWorkCountMax: Integer);
        procedure IdHTTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
        procedure IdHTTP1Status(ASender: TObject; const AStatus: TIdStatus;
          const AStatusText: string);
        procedure Button3Click(Sender: TObject);
      private
        AbortTransfer: Boolean; //是否中断
        BytesToTransfer: LongWord; //下载总大小
        procedure FtpDownLoad(aURL, aFile: string; bResume: Boolean);
        procedure HttpDownLoad(aURL, aFile: string; bResume: Boolean);
        procedure MyDownLoad(aURL, aFile: string; bResume: Boolean);
        function GetProt(aURL: string): Byte;
        function GetURLFileName(aURL: string): string;
        procedure GetFTPParams(aURL: string; var sName, sPass, sHost, sPort,
          sDir: string);
        { Private declarations }
      public
        { Public declarations }
      end;
    var
      Form1: TForm1;
    var
      AverageSpeed: Double = 0;
    implementation
    {$R *.dfm}
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      AbortTransfer := True;
    end;
    function TForm1.GetProt(aURL: string): Byte;
    begin //检测下载的地址是http还是ftp
      Result := 0;
      if Pos('http', LowerCase(aURL)) = 1 then
        Result := 1; //http协议
      if Pos('ftp', LowerCase(aURL)) = 1 then
        Result := 2; //ftp协议
    end;
    function TForm1.GetURLFileName(aURL: string): string;
    var
      i: integer;
      s: string;
    begin //返回下载地址的文件名
      s := aURL;
      i := Pos('/', s);
      while i <> 0 do //去掉"/"前面的内容剩下的就是文件名了
      begin
        Delete(s, 1, i);
        i := Pos('/', s);
      end;
      Result := s;
    end;
    procedure TForm1.GetFTPParams(aURL: string; var sName, sPass, sHost, sPort, sDir: string);
    var
      i, j: integer;
      s, tmp: string;
    begin //分析ftp地址的登陆用户名,密码和目录
      s := aURL;
      if Pos('ftp://', LowerCase(s)) <> 0 then //去掉ftp头
        Delete(s, 1, 6);
      i := Pos('@', s);
      if i <> 0 then //地址含用户名,也可能含密码
      begin
        tmp := Copy(s, 1, i - 1);
        s := copy(s, i+1, Length(s));
        j := Pos(':', tmp);
        if j <> 0 then //包含密码
        begin
          sName := Copy(tmp, 1, j - 1); //得到用户名
          sPass := Copy(tmp, j + 1, i - j - 1); //得到密码
        end else
        begin
          sName := tmp;
          sPass := Inputbox('输入框','请输入登陆ftp密码','');
        end;
      end else //匿名用户
      begin
        sName := 'anonymous';
        sPass := 'test@ftp.com';
      end;
      i := Pos(':', s);
      j := Pos('/', s);
      sHost := Copy(s, 1, j - 1); //主机
      if i <> 0 then //含端口
        sPort := Copy(s, i + 1, j - i - 1) else
        sPort := '21'; //默认21端口
      tmp := Copy(s, j + 1, Length(s));
      while j <> 0 do
      begin
        Delete(s, 1, j);
        j := Pos('/', s);
      end; //目录
      sDir := '/' + Copy(tmp, 1, Length(tmp) - Length(s) - 1);
    end;
    procedure TForm1.FtpDownLoad(aURL, aFile: string; bResume: Boolean);
    var
      tStream: TFileStream;
      sName, sPass, sHost, sPort, sDir: string;
    begin //ftp方式下载
      if FileExists(aFile) then //建立文件流
        tStream := TFileStream.Create(aFile, fmOpenWrite) else
        tStream := TFileStream.Create(aFile, fmCreate);
      GetFTPParams(aURL, sName, sPass, sHost, sPort, sDir);
      with IdFTP1 do
      try
        if Connected then Disconnect; //重新连接
        Username := sName;
        Password := sPass;
        Host := sHost;
        Port := StrToInt(sPort);
        Connect;
      except
        exit;
      end;
      IdFTP1.ChangeDir(sDir); //改变目录
      BytesToTransfer := IdFTP1.Size(aFile);
      try
        if bResume then //续传
        begin
          tStream.Position := tStream.Size;
          IdFTP1.Get(aFile, tStream, True);
        end else
        begin
          IdFTP1.Get(aFile, tStream, False);
        end;
      finally
        tStream.Free;
      end;
    end;
    procedure TForm1.HttpDownLoad(aURL, aFile: string; bResume: Boolean);
    var
      tStream: TFileStream;
    begin //Http方式下载
      if FileExists(aFile) then //如果文件已经存在
        tStream := TFileStream.Create(aFile, fmOpenWrite) else
        tStream := TFileStream.Create(aFile, fmCreate);
      if bResume then //续传方式
      begin
        IdHTTP1.Request.ContentRangeStart := tStream.Size - 1;
        tStream.Position := tStream.Size - 1; //移动到最后继续下载
        IdHTTP1.Head(aURL);
        IdHTTP1.Request.ContentRangeEnd := IdHTTP1.Response.ContentLength;
      end else //覆盖或新建方式
      begin
        IdHTTP1.Request.ContentRangeStart := 0;
      end;
      try
        IdHTTP1.Get(aURL, tStream); //开始下载
      finally
        tStream.Free;
      end;
    end;
    procedure TForm1.MyDownLoad(aURL, aFile: string; bResume: Boolean);
    begin
      case GetProt(aURL) of
        0: ShowMessage('不可识别的地址!');
        1: HttpDownLoad(aURL, aFile, bResume);
        2: FtpDownLoad(aURL, aFile, bResume);
      end;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    var
      aURL, aFile: string;
    begin
      aURL := ComboBox1.Text; //下载地址,例如"http://www.baidu.com/update/test.exe"
      aFile := GetURLFileName(aURL); //得到文件名,例如"test.exe"
      if FileExists(aFile) then
      begin
        case MessageDlg('文件已经存在,是否续传?', mtConfirmation, mbYesNoCancel, 0) of
          mrYes: MyDownLoad(aURL, aFile, True); //续传
          mrNo: MyDownLoad(aURL, aFile, False); //覆盖
          mrCancel: Exit; //取消
        end;
      end else MyDownLoad(aURL, aFile, False); //建立新文件下载
    end;
    procedure TForm1.IdHTTP1Work(Sender: TObject; AWorkMode: TWorkMode;
      const AWorkCount: Integer);
    begin
      if AbortTransfer then
      begin //中断下载
        IdHTTP1.Disconnect;
        IdFTP1.Abort;
      end;
      ProgressBar1.Position := AWorkCount;
      Application.ProcessMessages;
    end;
    procedure TForm1.IdHTTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
      const AWorkCountMax: Integer);
    begin
      AbortTransfer := False;
      if AWorkCountMax > 0 then
        ProgressBar1.Max := AWorkCountMax else
        ProgressBar1.Max := BytesToTransfer;
    end;
    procedure TForm1.IdHTTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
    begin
      ProgressBar1.Position := 0;
    end;
    procedure TForm1.IdHTTP1Status(ASender: TObject; const AStatus: TIdStatus;
      const AStatusText: string);
    begin
      ListBox1.ItemIndex := ListBox1.Items.Add(AStatusText);
    end;
    procedure TForm1.Button3Click(Sender: TObject);
    begin
      Close;
    end;
    end.

    http://www.codefans.net/articles/1342.shtml

    Delphi完成的断点续传例子,在网络应用中,断点续传是相当实用的,比如自动升级、或下载程序中,都可以用到。在Delphi7中,可以使用TIdHTTP和TIdFTP组件实现基于HTTP协议的断点续传和FTP协议的断点续传,都是使用的Indy系列组件,使用方法大同小异,下面来看运行效果图:

    unit Unit1;
    interface
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls, IdFTP, IdBaseComponent, IdComponent,
      IdTCPConnection, IdTCPClient, IdHTTP, IdHTTPHeaderInfo, ExtCtrls;
    type
      TForm1 = class(TForm)
        ListBox1: TListBox;
        Panel1: TPanel;
        Label1: TLabel;
        Label2: TLabel;
        Button1: TButton;
        ProgressBar1: TProgressBar;
        Button2: TButton;
        IdHTTP1: TIdHTTP;
        IdFTP1: TIdFTP;
        Button3: TButton;
        ComboBox1: TComboBox;
        procedure Button2Click(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure IdHTTP1Work(Sender: TObject; AWorkMode: TWorkMode;
          const AWorkCount: Integer);
        procedure IdHTTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
          const AWorkCountMax: Integer);
        procedure IdHTTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
        procedure IdHTTP1Status(ASender: TObject; const AStatus: TIdStatus;
          const AStatusText: string);
        procedure Button3Click(Sender: TObject);
      private
        AbortTransfer: Boolean; //是否中断
        BytesToTransfer: LongWord; //下载总大小
        procedure FtpDownLoad(aURL, aFile: string; bResume: Boolean);
        procedure HttpDownLoad(aURL, aFile: string; bResume: Boolean);
        procedure MyDownLoad(aURL, aFile: string; bResume: Boolean);
        function GetProt(aURL: string): Byte;
        function GetURLFileName(aURL: string): string;
        procedure GetFTPParams(aURL: string; var sName, sPass, sHost, sPort,
          sDir: string);
        { Private declarations }
      public
        { Public declarations }
      end;
    var
      Form1: TForm1;
    var
      AverageSpeed: Double = 0;
    implementation
    {$R *.dfm}
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      AbortTransfer := True;
    end;
    function TForm1.GetProt(aURL: string): Byte;
    begin //检测下载的地址是http还是ftp
      Result := 0;
      if Pos('http', LowerCase(aURL)) = 1 then
        Result := 1; //http协议
      if Pos('ftp', LowerCase(aURL)) = 1 then
        Result := 2; //ftp协议
    end;
    function TForm1.GetURLFileName(aURL: string): string;
    var
      i: integer;
      s: string;
    begin //返回下载地址的文件名
      s := aURL;
      i := Pos('/', s);
      while i <> 0 do //去掉"/"前面的内容剩下的就是文件名了
      begin
        Delete(s, 1, i);
        i := Pos('/', s);
      end;
      Result := s;
    end;
    procedure TForm1.GetFTPParams(aURL: string; var sName, sPass, sHost, sPort, sDir: string);
    var
      i, j: integer;
      s, tmp: string;
    begin //分析ftp地址的登陆用户名,密码和目录
      s := aURL;
      if Pos('ftp://', LowerCase(s)) <> 0 then //去掉ftp头
        Delete(s, 1, 6);
      i := Pos('@', s);
      if i <> 0 then //地址含用户名,也可能含密码
      begin
        tmp := Copy(s, 1, i - 1);
        s := copy(s, i+1, Length(s));
        j := Pos(':', tmp);
        if j <> 0 then //包含密码
        begin
          sName := Copy(tmp, 1, j - 1); //得到用户名
          sPass := Copy(tmp, j + 1, i - j - 1); //得到密码
        end else
        begin
          sName := tmp;
          sPass := Inputbox('输入框','请输入登陆ftp密码','');
        end;
      end else //匿名用户
      begin
        sName := 'anonymous';
        sPass := 'test@ftp.com';
      end;
      i := Pos(':', s);
      j := Pos('/', s);
      sHost := Copy(s, 1, j - 1); //主机
      if i <> 0 then //含端口
        sPort := Copy(s, i + 1, j - i - 1) else
        sPort := '21'; //默认21端口
      tmp := Copy(s, j + 1, Length(s));
      while j <> 0 do
      begin
        Delete(s, 1, j);
        j := Pos('/', s);
      end; //目录
      sDir := '/' + Copy(tmp, 1, Length(tmp) - Length(s) - 1);
    end;
    procedure TForm1.FtpDownLoad(aURL, aFile: string; bResume: Boolean);
    var
      tStream: TFileStream;
      sName, sPass, sHost, sPort, sDir: string;
    begin //ftp方式下载
      if FileExists(aFile) then //建立文件流
        tStream := TFileStream.Create(aFile, fmOpenWrite) else
        tStream := TFileStream.Create(aFile, fmCreate);
      GetFTPParams(aURL, sName, sPass, sHost, sPort, sDir);
      with IdFTP1 do
      try
        if Connected then Disconnect; //重新连接
        Username := sName;
        Password := sPass;
        Host := sHost;
        Port := StrToInt(sPort);
        Connect;
      except
        exit;
      end;
      IdFTP1.ChangeDir(sDir); //改变目录
      BytesToTransfer := IdFTP1.Size(aFile);
      try
        if bResume then //续传
        begin
          tStream.Position := tStream.Size;
          IdFTP1.Get(aFile, tStream, True);
        end else
        begin
          IdFTP1.Get(aFile, tStream, False);
        end;
      finally
        tStream.Free;
      end;
    end;
    procedure TForm1.HttpDownLoad(aURL, aFile: string; bResume: Boolean);
    var
      tStream: TFileStream;
    begin //Http方式下载
      if FileExists(aFile) then //如果文件已经存在
        tStream := TFileStream.Create(aFile, fmOpenWrite) else
        tStream := TFileStream.Create(aFile, fmCreate);
      if bResume then //续传方式
      begin
        IdHTTP1.Request.ContentRangeStart := tStream.Size - 1;
        tStream.Position := tStream.Size - 1; //移动到最后继续下载
        IdHTTP1.Head(aURL);
        IdHTTP1.Request.ContentRangeEnd := IdHTTP1.Response.ContentLength;
      end else //覆盖或新建方式
      begin
        IdHTTP1.Request.ContentRangeStart := 0;
      end;
      try
        IdHTTP1.Get(aURL, tStream); //开始下载
      finally
        tStream.Free;
      end;
    end;
    procedure TForm1.MyDownLoad(aURL, aFile: string; bResume: Boolean);
    begin
      case GetProt(aURL) of
        0: ShowMessage('不可识别的地址!');
        1: HttpDownLoad(aURL, aFile, bResume);
        2: FtpDownLoad(aURL, aFile, bResume);
      end;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    var
      aURL, aFile: string;
    begin
      aURL := ComboBox1.Text; //下载地址,例如"http://www.baidu.com/update/test.exe"
      aFile := GetURLFileName(aURL); //得到文件名,例如"test.exe"
      if FileExists(aFile) then
      begin
        case MessageDlg('文件已经存在,是否续传?', mtConfirmation, mbYesNoCancel, 0) of
          mrYes: MyDownLoad(aURL, aFile, True); //续传
          mrNo: MyDownLoad(aURL, aFile, False); //覆盖
          mrCancel: Exit; //取消
        end;
      end else MyDownLoad(aURL, aFile, False); //建立新文件下载
    end;
    procedure TForm1.IdHTTP1Work(Sender: TObject; AWorkMode: TWorkMode;
      const AWorkCount: Integer);
    begin
      if AbortTransfer then
      begin //中断下载
        IdHTTP1.Disconnect;
        IdFTP1.Abort;
      end;
      ProgressBar1.Position := AWorkCount;
      Application.ProcessMessages;
    end;
    procedure TForm1.IdHTTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
      const AWorkCountMax: Integer);
    begin
      AbortTransfer := False;
      if AWorkCountMax > 0 then
        ProgressBar1.Max := AWorkCountMax else
        ProgressBar1.Max := BytesToTransfer;
    end;
    procedure TForm1.IdHTTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
    begin
      ProgressBar1.Position := 0;
    end;
    procedure TForm1.IdHTTP1Status(ASender: TObject; const AStatus: TIdStatus;
      const AStatusText: string);
    begin
      ListBox1.ItemIndex := ListBox1.Items.Add(AStatusText);
    end;
    procedure TForm1.Button3Click(Sender: TObject);
    begin
      Close;
    end;
    end.
  • 相关阅读:
    poj 1113 Wall 凸包的应用
    NYOJ 78 圈水池 (入门级凸包)
    Monotone Chain Convex Hull(单调链凸包)
    poj Sudoku(数独) DFS
    poj 3009 Curling 2.0(dfs)
    poj 3083 Children of the Candy Corn
    Python join()方法
    通过FISH和下一代测序检测肺腺癌ALK基因融合比较
    华大病原微生物检测
    NGS检测ALK融合大起底--转载
  • 原文地址:https://www.cnblogs.com/zhangzhifeng/p/6141557.html
Copyright © 2011-2022 走看看