全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1993
推到 Plurk!
推到 Facebook!

請問大大有關處理大量的data有什麼好方法

尚未結案
SamSam1230
中階會員


發表:128
回覆:178
積分:65
註冊:2004-12-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-06-23 16:55:29 IP:218.103.xxx.xxx 未訂閱
如圖中 我的data以tstringlist方式存放 第一步 有很大量的data 會傳給我我會以Tstringlist 存放 如圖中的 File as tstringlist 之後因為這data 是以token format方式所以我要把data extract出來 如圖中, data 0 .. data 1 .. data 2.....datax 之後會再一個data一個data 放到database 裡的相對的field get token 我是用while loop 的方式 而第一步是用一個for 包起來 一行一行的做 但發現這樣很慢,想問各位大大有經驗可以告訴我有什麼方法呢? p.s 我也想過用memory 的方式但我的data field 大約有10個
suda
一般會員


發表:17
回覆:63
積分:16
註冊:2002-05-10

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-06-23 23:58:27 IP:218.175.xxx.xxx 未訂閱
如果是sqlserver 就直轉成sql的insert or update 指令,避免經由DataField 來處理
SamSam1230
中階會員


發表:128
回覆:178
積分:65
註冊:2004-12-23

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-06-24 12:25:33 IP:218.103.xxx.xxx 未訂閱
我不太明白你的意思 但是我的問題是有很多data 要放到database 在放到database 之前要做一些處理而這些處就是把一大串的data tokensizer 我現在有一大堆的data, 是一串一串, 而每一串的data裡都是用'@'分格每一個field的data,所以我用了一個for loop 去看每一串,在每一串裡又用了while loop 的方式做tokensizer, 之後再把結果放到Tstringlist 裡再放到database 相對的field 的位置. 那我發現的是那個tokensize 不知道是不是太久了 而且那個for loop 也是 所以想請教各位大大有沒有好的建議 謝謝
supman
尊榮會員


發表:29
回覆:770
積分:924
註冊:2002-04-22

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-06-24 13:04:34 IP:61.70.xxx.xxx 未訂閱
您好: Data0@Data1...的資料,使用以下方式做切割不曉得會不會快些,您試試. var S:String TStringList List; begin List:=TStringList.Create(); S:=StringReplace(S,'@',#13#10,[rfReplaceAll]); List->Text:=S; end; 發表人 - supman 於 2005/06/24 13:06:48
suda
一般會員


發表:17
回覆:63
積分:16
註冊:2002-05-10

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-06-24 17:25:13 IP:218.175.xxx.xxx 未訂閱
請問是慢在拆成stringlis, 還是插入資料庫時慢.
change.jian
版主


發表:29
回覆:620
積分:439
註冊:2003-06-02

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-06-25 09:41:47 IP:61.218.xxx.xxx 未訂閱
to SamSam1230: 1.TStringList只適用在處理小量的資料,如果你文字檔是數十MB的那種文字檔,那麼勸你不要用TStringList,改用TextFile的方式,自已控制. 2.如果後端資料是可以寫 store procedure的,那麼建議做法是把文字檔先直接寫入資料庫內,然後在寫store procedure,一筆一筆的把資料拆成要的格式,寫入到table裡.(如果非常在意速度的話) 3.較簡單的做法,是先把Ultra Edit之類的軟體,把文字檔先切成檔案小一點的檔案,然後再以TStringList去處理,利用TStringList.DelimitedText的方法,可以很容易的把資料拆開來. 供參考
SamSam1230
中階會員


發表:128
回覆:178
積分:65
註冊:2004-12-23

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-06-27 09:44:54 IP:218.103.xxx.xxx 未訂閱
謝謝change.jian大大的建議 to suda : 我是慢在拆成stringlist
change.jian
版主


發表:29
回覆:620
積分:439
註冊:2003-06-02

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-06-27 10:54:18 IP:61.218.xxx.xxx 未訂閱
你是怎麼拆成到StringList的?這個部份應該不會慢才是!可以把你的做法post上來或是把code post上來看?    
引言: 謝謝change.jian大大的建議 to suda : 我是慢在拆成stringlist
SamSam1230
中階會員


發表:128
回覆:178
積分:65
註冊:2004-12-23

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-06-27 11:07:27 IP:218.103.xxx.xxx 未訂閱
 
for i := 2 to LocalSourceListArray[cnt].Count-1 do
begin
     buff := ExtractData(ListViewer.LocalSourceListArray[cnt],Separator,cnt1); 
     Mlist.Assign(buff);
     buff.Free();
end;    Function ExtractData(IPStringlist : Tstringlist;Separator : char;index:integer): Tstringlist;
var
   TempList : Tstringlist;
begin
     Result := Tstringlist.Create;
     TempList := Tstringlist.Create;
     Split(IPStringlist[index],Separator,TempList);
     Result.assign(TempList);
     Templist.Free;
end;    procedure Split(const S: String;Separator: Char;MyStringList1 : TStringList) overload;
var Start: integer;
begin
   Start := 1;
   While Start <= Length(S) do
     MyStringList1.Add(GetNextToken(S, Separator, Start)) ;
end;    function GetNextToken(Const S: string;Separator: char;var StartPos: integer): String;
var Index: integer;
begin
   Result := '';       While (S[StartPos] = Separator)
   and (StartPos <= length(S))do
    StartPos := StartPos   1;       if StartPos > length(S) then Exit;       Index := StartPos;       While (S[Index] <> Separator)
   and (Index <= length(S))do
    Index := Index   1;       Result := Copy(S, StartPos, Index - StartPos) ;       StartPos := Index   1;
end;    
supman
尊榮會員


發表:29
回覆:770
積分:924
註冊:2002-04-22

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-06-27 11:24:51 IP:61.70.xxx.xxx 未訂閱
您好: 我上面那篇寫的是讓TStringList自己做拆解的動作,不曉得您有沒有去試過? ------- 您好: Data0@Data1...的資料,使用以下方式做切割不曉得會不會快些,您試試. var S:String TStringList List; begin List:=TStringList.Create(); S:=StringReplace(S,'@',#13#10,[rfReplaceAll]);//將@用換行碼取代,轉換成TStringList後,你就可以直接使用Strings存取List.Strings[0](表示第一個Data),不需要自己去寫Token. List.Text:=S; end; 發表人 - supman 於 2005/06/27 11:33:29
SamSam1230
中階會員


發表:128
回覆:178
積分:65
註冊:2004-12-23

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-06-27 11:36:48 IP:218.103.xxx.xxx 未訂閱
supman您好: 我有試過了 應該差別不多 所以我還在查 順口一問, 請問知道有好用的 profiler 嗎?
suda
一般會員


發表:17
回覆:63
積分:16
註冊:2002-05-10

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-06-27 11:57:50 IP:218.175.xxx.xxx 未訂閱
ExtractData中的list可以用一個全域變數必免重覆create and free Tstringlist.Capacity可以先配置list的大小,可加快速度 請你放一小段資料上來,說明file的數量及大小,是一次還是常用 1.delphi 有一個TParser可以參考一下 2.或是轉成csv格式匯入資料庫 3.下列是一個搜尋罝換的function,可以置換的地方換成你想要的function procedure TForm1.Button1Click(Sender: TObject); var src: Tstringstream; tar: Tstringstream; c: char; i: integer; serachStr: string; serachStrLength: integer; replacestr: string; replacestrLength: integer; procedure readSrc; begin src.read(c, 1); end; begin serachStr := 'abc'; serachStrLength := length(serachStr); replacestr := 'def'; replacestrLength := length(replacestr); // src:=tfilestream.create(Filename,fmOpenRead); src := tstringstream.create('ababcdeftkgt'); tar := tstringstream.Create(''); i := 1; while src.position < src.Size do begin readSrc; if c = serachStr[i] then begin inc(i); if i = serachStrLength 1 then begin tar.Write(replacestr[1], replacestrLength); i := 1; end; end else begin //rollback if i > 1 then begin src.Position := src.Position - i; tar.CopyFrom(src, i - 1); i := 1; end else begin tar.Write(c, 1); end; end; end; // while showmessage(format('src:%s tar:%s', [src.DataString, tar.DataString])); end;
change.jian
版主


發表:29
回覆:620
積分:439
註冊:2003-06-02

發送簡訊給我
#13 引用回覆 回覆 發表時間:2005-06-27 13:34:17 IP:61.218.xxx.xxx 未訂閱
to SamSam1230: 我剛好有跟你一樣的事情,給你個範例參考一下:
unit Unit1;    interface    uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Buttons, StdCtrls, ExtCtrls;    type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    leFileName: TLabeledEdit;
    SpeedButton1: TSpeedButton;
    ListBox2: TListBox;
    SpeedButton2: TSpeedButton;
    procedure SpeedButton1Click(Sender: TObject);
    procedure SpeedButton2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FssTemp:TStringList;
  public
    { Public declarations }
  end;    var
  Form1: TForm1;    implementation    {$R *.dfm}    procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  od:TOpenDialog;
begin
  od:=TOpenDialog.Create(Self);
  try
    od.InitialDir:=ExtractFilePath(Application.ExeName);
    if od.Execute then
    begin
      leFileName.Text:=od.FileName;
      ListBox1.Items.LoadFromFile(leFileName.Text); //我是把文字檔的內容先放到ListBox1裡,因為文字檔不大
    end;
  finally
    od.Free;
  end;
end;    procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
  //這裡是把ListBox1裡被選的該筆資料放到ListBox2裡,並且已經拆開來了
  FssTemp.DelimitedText:=ListBox1.Items.Strings[ListBox1.itemIndex];
  ListBox2.Items.Assign(FssTemp);
end;    procedure TForm1.FormCreate(Sender: TObject);
begin
  FssTemp:=TStringList.Create;
  FssTemp.Delimiter:='@'; //利用TStringList.Delimiter及TStringList.DelimitedText,很方便處理的
end;    end.
執行畫面
ph
一般會員


發表:3
回覆:27
積分:11
註冊:2003-09-28

發送簡訊給我
#14 引用回覆 回覆 發表時間:2005-06-27 22:38:15 IP:218.160.xxx.xxx 未訂閱
procedure TForm2.Button1Click(Sender: TObject);
Var str1:TStringList;
    I:Integer;    begin
  Str1:=TStringList.Create;
  Str1.LoadFromFile('');
  For I:=0 To Str1.Count -1 do
  begin
    if Str1.Text <> '' then
    begin
      GetPosData(Str1.Text,'@');  //拆解字串到Array
      PosDataToDB;  //將Array的資料寫到Database
    end;      end;
end;    procedure TForm2.GetPosData(S:String,Seperate:String);
Var Arr1:Array[0..255] of String;
    I:Integer;
begin
  I:=0;
  While Length(S) >0 Do
  begin
    if Pos(Seperate,S) > 0 then
    begin
      I:=I 1;
      Arr1[I]:=Copy(S,1,Pos(S,Seperate)-1));
      S:=Copy(S,Pos(S,Seperate) 1),Length(S)-Pos(S,Seperate)));
    end
    else
    begin
      I:=I 1;
      Arr1[I]:=S;
      S:='';
    end;
  end;    end;    
山即是我 我即是山
------
學了這麼久還是沒進步
SamSam1230
中階會員


發表:128
回覆:178
積分:65
註冊:2004-12-23

發送簡訊給我
#15 引用回覆 回覆 發表時間:2005-06-28 09:29:35 IP:218.103.xxx.xxx 未訂閱
我用的是delphi 4 好像 Tstringlist 跟 tstring 都沒有 DelimitedText 也謝謝大大的提供
shieh2700
高階會員


發表:0
回覆:127
積分:100
註冊:2002-06-13

發送簡訊給我
#16 引用回覆 回覆 發表時間:2005-06-29 01:13:30 IP:61.229.xxx.xxx 未訂閱
procedure readTextFile(filename: string);
var
  f:TextFile;
  r:string;
  s:TStrings;
  i:integer;
begin
  if FileExists(filename) then begin
    s := TStringList.Create;
    AssignFile(f, filename);
    Reset(f);
    while not EOF(f) do begin
      ReadLn(f,r);
      s.Text := StringReplace(r,'@',#13#10,[rfReplaceAll]);
      //顯示各欄位的值 {想幹什麼就幹什麼}
      for i := 0 to s.Count-1 do
        ShowMessage(s[i]);
    end;
    CloseFile(F);
    s.Free;
  end;
end;
系統時間:2024-04-24 12:36:48
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!