2016-07-26 79 views
0

什麼是最好的方法來做到這一點:我有一個txt文件充滿了網址,我必須檢查所有使用idHTTP組件,只有一個簡單的檢查從網絡服務器,下載HTML和找到匹配,我希望它是快速的,有不同類型的線程,我不知道什麼是最好的使用,TParallel forTask threads或普通線程? 我之前嘗試過TParallel for和我被困在AV,我也試過Task threads,但它不快,http請求變慢了,我也試過普通線程,我不知道如何使用它,因爲它使用複雜。
注意:請不要downvote我只需要專家的建議。謝謝什麼是最好的方法來提出http請求

+1

你是什麼意思的「檢查」?你的意思是隻下載頭文件嗎?檢查它是否是有效的URL?檢查在該URL找到的一些數據/內容?你真正的問題是否使用'TParallel'或'TTask'來達到你的目的?在任何情況下,所有這些都是廣泛的問題,吸引了斟酌答案 - 這兩個都在這裏皺起了眉頭。你試過什麼了?你有沒有在這兩種可能的解決方案之間觀察到什麼優點和缺點? –

+0

@JerryDodge下載html並尋找匹配,添加infomramtion。 – cyberdude

回答

1

首先建議:不要使用Indy。使用THTTPClient(本機System.Net.HttpClient) - 本機爲Delphi XE?+

我仍在使用舊的TThreads。我只能用TThread提出建議。

工作流程:

主線程 - 逐行讀取您的TXT文件。 行後,您創建新的線程,這是從WWW下載信息。

示例應用程序:

unit ufmMain; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, 
    System.SysUtils, System.Variants, 
    { TThread } 
    System.Classes, 
    Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; 

type 
    TForm1 = class(TForm) 
    Button1: TButton; 
    procedure Button1Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

    TLoad = class(TThread) 
    protected 
    FURL, 
    FOutputFileName: String; 

    procedure Execute; override; 
    public 
    constructor Create(const AURL, AOutputFileName: String); overload; 
    end; 

    HTTP = class 
    public 
    class procedure Get(const AURL: String; out AOutputStream: TMemoryStream); 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

uses 
    { THTTPClient } 
    System.Net.HttpClient; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    LLoad: TLoad; 
    LFile: TextFile; 
    LCycle: Integer; 
    LUrl: String; 
begin 
    LCycle := 0; 

    AssignFile(LFile, 'urls.txt'); 
    try 
    Reset(LFile); 

    while not Eof(LFile) do 
     begin 
     { Using for generate file name. All file names must be unique } 
     Inc(LCycle); 

     { Read next URL } 
     ReadLn(LFile, LUrl); 

     { Create new thread } 
     LLoad := TLoad.Create(LUrl, 'Output file No ' + LCycle.ToString + '.htm'); 
     LLoad.FreeOnTerminate := True; 
     LLoad.Start; 
     end; 
    finally 
    CloseFile(LFile); 
    end; 
end; 

{ TLoad } 

constructor TLoad.Create(const AURL, AOutputFileName: String); 
begin 
    inherited Create(True); 

    FURL := AURL; 
    FOutputFileName := AOutputFileName; 
end; 

procedure TLoad.Execute; 
var 
    LResponse: TMemoryStream; 
begin 
    inherited; 

    LResponse := TStringStream.Create; 
    try 
    HTTP.Get(FURL, LResponse); 

    { Save result to file } 
    LResponse.SaveToFile(GetCurrentDir + PathDelim + FOutputFileName); 
    finally 
    LResponse.Free; 
    end; 
end; 

{ HTTP } 

class procedure HTTP.Get(const AURL: String; out AOutputStream: TMemoryStream); 
var 
    LStream: TStream; 
    LHTTPClient: THTTPClient; 
begin 
    LHTTPClient := THTTPClient.Create; 
    try 
    LStream := LHTTPClient.Get(AURL).ContentStream; 

    AOutputStream.CopyFrom(LStream, LStream.Size); 
    finally 
    LHTTPClient.Free; 
    end; 
end; 

end. 

爲什麼我反對印:

1)THTTPClient並不需要額外的DLL使用SSL協議

2)THTTPClient是德爾福XE8

現代

3)我的主觀觀點:THTTPClient的工作更順利(問題更少),然後Indy庫。過去10年我使用過Indy,但現在我所有支持的項目都轉移到了THTTPClient上。

+0

爲什麼你建議不要使用Indy? – mjn42

+0

@ mjn42 - 爲什麼我對印: 1)THTTPClient並不需要額外的DLL使用SSL協議 2)THTTPClient是德爾福XE8現代 3)我的主觀意見:順利得多THTTPClient廠(少問題)然後Indy圖書館。過去10年我使用過Indy,但現在我所有支持的項目都轉移到了THTTPClient上。 – Zam

+0

看看這裏[http://stackoverflow.com/posts/comments/64687148?noredirect=1] – cyberdude

0

您可以使用TTask和Indy(TIdHTTP)。例如:

function GetUrl(const aUrl: string): ITask; 
begin 
    Result := TTask.Run(
    procedure 
    var 
     FOutput: string; 
     FHTTP: TIdHTTP; 
    begin 
     FHTTP:=TIdHTTP.Create(nil); 
     try 
     try 
      FOutput:=FHTTP.Get(aUrl); 
     except 
      // handle errors 
     end; 
     finally 
     FHTTP.Free; 
     end; 

     TThread.Synchronize(nil, 
     procedure 
     begin 
      ProcessOutput(FOutput); // send your output/result to main thread 
     end); 
    end); 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    i: Integer; 
    list: TStringList; 
begin 
    list:=TStringList.Create; 
    try 
    list.LoadFromFile('yourfile.txt'); 

    // get all your urls 
    // you should control how many threads run at the same time 
    for i := 0 to list.Count-1 do 
     GetUrl(list[i]); 
    finally 
    list.Free; 
    end; 
end; 
+0

我想用'ShowMessage(FOutput);'不是個好主意。 – Zam

+0

我不認爲任何人會用它來閱讀這麼長的來源。那是處理數據的地方。我會爲你更新它。 – smooty86

+0

我之前使用過這種方法,但是如果您在循環中使用多個帖子,則此帖子響應會逐漸變慢 – cyberdude

相關問題