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

請教"大量文字資料檔,以TStringList載入"問題

答題得分者是:shunaaron
ac910127
一般會員


發表:7
回覆:27
積分:11
註冊:2009-11-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2010-11-29 17:34:58 IP:124.219.xxx.xxx 訂閱
各位前輩 您們好

小弟在此有一問題,請前輩們不吝惜給我建議與指教。

目前有一ID對照表(XXXX.txt),內容為多筆身分證字號(大概二百萬筆左右),大小約100多MB,
由於程式執行過程,需要此表對照。
第一時間小弟想到以"TStringList"方式載入,利用TStringList特性方便找尋KEY值。但問題來了

1 : TStringList能負載的大小為多少,以小弟目前的認知,一百多MB是OK的,實不知道真實上限為多少?
由於ID對照表可能隨時間增長,怕無法負載!!

2 : 在找尋TStringList內容值時,小弟利用
tIntIndex:=TStringList.IndexOf('S123456789');來取得位子,可是不知是因為太大量還是怎樣?
回傳的 tIntIndex:=-1; << 表示沒找到。小弟可確認"S123456789"確實存在,不過位子在一百八十幾萬的位子。
因此小弟改以利用迴圈方式找尋
for i=0 to TStringList.Count-1 do begin
......
......
end; 這樣的話就可正確找到資料。不知前輩能否指導兩種方式為啥出現不同的結果,差別在哪 ???

3 : 由於ID對照表可能會隨著時間而量不斷增加,深怕"TStringList"日後無法負載如此大量的資料,尋找速度變慢之類的。
小弟目前只想到以"TStringList"來處理,不知前輩可否其他建議 ?

以上,先感謝前輩們的指導!!

編輯記錄
ac910127 重新編輯於 2010-11-30 19:33:51, 註解 無‧
pprayer
高階會員


發表:35
回覆:185
積分:174
註冊:2002-03-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2010-11-29 20:41:46 IP:114.32.xxx.xxx 訂閱
TStringList 應該是可以暫存這麼多的資料,除非你硬碟不夠拿來做虛擬記憶體。

若你擔心效能跟記憶體的問題也可以用 TFileStream
一段一段buffer去取得硬碟上的資料
應該會比較快
ac910127
一般會員


發表:7
回覆:27
積分:11
註冊:2009-11-06

發送簡訊給我
#3 引用回覆 回覆 發表時間:2010-11-30 10:27:23 IP:124.219.xxx.xxx 訂閱
感謝您的回覆!!

以小弟的認知,TFileStream在作查詢資料時,相對於TStringList麻煩些,
但小弟會在試看看前輩的建議。

不知前輩可否為小弟解答第二個問題 ??

再次感謝您的回覆!!

===================引 用 pprayer 文 章===================
TStringList 應該是可以暫存這麼多的資料,除非你硬碟不夠拿來做虛擬記憶體。

若你擔心效能跟記憶體的問題也可以用 TFileStream
一段一段buffer去取得硬碟上的資料
應該會比較快
編輯記錄
ac910127 重新編輯於 2010-11-29 19:28:06, 註解 無‧
shunaaron
高階會員


發表:13
回覆:94
積分:106
註冊:2006-10-06

發送簡訊給我
#4 引用回覆 回覆 發表時間:2010-11-30 11:32:48 IP:124.65.xxx.xxx 訂閱
tIntIndex:=TStringList.IndexOf('S123456789');
IndexO最後是用PChar來比對,
看一下文字檔格式內碼為何

===================引 用 ac910127 文 章===================
各位前輩 您們好

小弟在此有一問題,請前輩們不吝惜給我建議與指教。

目前有一ID對照表(XXXX.txt),內容為多筆身分證字號(大概二百萬筆左右),大小約100多MB,
由於程式執行過程,需要此表對照。
第一時間小弟想到以"TStringList"方式載入,利用TStringList特性方便找尋KEY值。但問題來了

1 : TStringList能負載的大小為多少,以小弟目前的認知,一百多MB是OK的,實不知道真實上限為多少?
由於ID對照表可能隨時間增長,怕無法負載!!

2 : 在找尋TStringList內容值時,小弟利用
tIntIndex:=TStringList.IndexOf('S123456789');來取得位子,可是不知是因為太大量還是怎樣?
回傳的 tIntIndex:=-1; << 表示沒找到。小弟可確認"S123456789"確實存在,不過位子在一百八十幾萬的位子。
因此小弟改以利用迴圈方式找尋
for i=0 to TStringList.Count-1 do begin
......
......
end; 這樣的話就可正確找到資料。不知前輩能否指導兩種方式為啥出現不同的結果,差別在哪 ???

3: 由於ID對照表可能會隨著時間而量不斷增加,深怕"TStringList"日後無法負載如此大量的資料,尋找速度變慢之類的。
小弟目前只想到以"TStringList"來處理,不知前輩可否其他建議 ?

以上,先感謝前輩們的指導!!

------
程式沒有這麼難
只是還沒打通其中要絕
max5020
資深會員


發表:30
回覆:277
積分:321
註冊:2003-06-04

發送簡訊給我
#5 引用回覆 回覆 發表時間:2010-11-30 13:31:05 IP:211.22.xxx.xxx 訂閱
建議將文字檔載入資料庫後,
再用SQL查詢,
應該會快一些,
如果文字檔內容有變動時,
建議先更新資料表記錄,
ac910127
一般會員


發表:7
回覆:27
積分:11
註冊:2009-11-06

發送簡訊給我
#6 引用回覆 回覆 發表時間:2010-11-30 15:00:57 IP:124.219.xxx.xxx 訂閱
感謝大大的回應!!

文字檔內容包含"一些特殊字元",故格式內碼應該為"Unicode"編碼方式存儲
另外小弟使用的Delphi版本為 Delphi2010

請教大大這是否有影響 ?

再次感謝大大的回應!!
===================引 用 shunaaron 文 章===================
tIntIndex:=TStringList.IndexOf('S123456789');
IndexO最後是用PChar來比對,
看一下文字檔格式內碼為何

ac910127
一般會員


發表:7
回覆:27
積分:11
註冊:2009-11-06

發送簡訊給我
#7 引用回覆 回覆 發表時間:2010-11-30 15:50:20 IP:124.219.xxx.xxx 訂閱
感謝您的回覆!!

小弟一開始也有朝此方向想,只不過"以文字檔方式
存放ID對照"是需求方舊有的方式,如何產生此ID對照檔(未知人撰寫)
並非小弟所知。若要修改此方式,需要再與需求方協商討論。

再次感謝大大的回覆!!
===================引 用 max5020 文 章===================
建議將文字檔載入資料庫後,
再用SQL查詢,
應該會快一些,
如果文字檔內容有變動時,
建議先更新資料表記錄,
shunaaron
高階會員


發表:13
回覆:94
積分:106
註冊:2006-10-06

發送簡訊給我
#8 引用回覆 回覆 發表時間:2010-11-30 23:27:01 IP:123.127.xxx.xxx 訂閱
如果文檔確認是unicode的話,那先除去編碼問題
可試下TStringList.find('你要找的字串',第幾個指標開始找)
假設有100萬筆資料,分100次去做比對,試看看吧。
第一次給0....之後給10001....20001
可以自己在調看看可以到多少
不過一次應極限應在3萬行...(2^16)猜測
===================引 用 ac910127 文 章===================
感謝大大的回應!!

文字檔內容包含"一些特殊字元",故格式內碼應該為"Unicode"編碼方式存儲
另外小弟使用的Delphi版本為 Delphi2010

請教大大這是否有影響 ?

再次感謝大大的回應!!
===================引 用 shunaaron 文 章===================
tIntIndex:=TStringList.IndexOf('S123456789');
IndexO最後是用PChar來比對,
看一下文字檔格式內碼為何

------
程式沒有這麼難
只是還沒打通其中要絕
ac910127
一般會員


發表:7
回覆:27
積分:11
註冊:2009-11-06

發送簡訊給我
#9 引用回覆 回覆 發表時間:2010-12-01 10:32:49 IP:124.219.xxx.xxx 訂閱
感謝大大再次的回覆,並提供建議。

由於不太清楚TStringList.Find 的用法,故在看了下HELP,並根據HELP提供的範例
與大大的建議,寫兩段Code !!

Code 1 - 根據HELP的範例
[code delphi]
procedure TForm1.Button1Click(Sender: TObject);
var
IDList : TStringList;
tIntFund : Integer;
tA: Extended; //紀錄處理時間
begin
IDList:=TStringList.Create;
tA:=Now;
IDList.LoadFromFile('C:\123456.txt');
IDList.Sort; //根據 HELP說明 需要sort
if IDList.Find('0000003BCA',tIntFund) then begin //在1822378的位置
Memo1.Lines.Add(IntToStr(tIntFund)); //有發現時 顯示所在位置
Memo1.Lines.Add(IDList.Strings[tIntFund]); //有發現時 顯示內容
Memo1.Lines.Add(FormatDateTime('HH:NN:SS:ZZZ',Now-tA)); //顯示處理時間
end;
IDList.Free;
end;
[/code]

Code 2 - 根據大大的建議
[code delphi]
procedure TForm1.Button2Click(Sender: TObject);
var
IDList : TStringList;
tIntFund : Integer;
tA: Extended;
begin
IDList:=TStringList.Create;
tA:=Now;
IDList.LoadFromFile('C:\123456.txt');
IDList.Sort;
tIntFund:=0;
while tIntFund > IDList.Count do begin
if IDList.Find('0000003BCA',tIntFund) then begin //在1822378的位置
Memo1.Lines.Add(IDList.Strings[tIntFund]); //有發現時 顯示內容
Memo1.Lines.Add(FormatDateTime('HH:NN:SS:ZZZ',Now-tA)); //顯示處理時間
break;
end else begin
Inc(tIntFund,30000); //沒有發現時,起始位置加三萬
end;
end;
IDList.Free;
end;
[/code]
以上兩種方式均無法找到。不知是小弟哪邊錯誤了!!!

另外,TStrginList.Find 是否是從Index的位置開始搜尋 到 最尾端??
還是 ??
煩請大大再次為小弟解惑 !!

再次感謝大大的回覆 !!


PS:本來想上傳ID對照檔,可是小弟好像沒辦法上傳檔案了,以下提供ID對照表格式
身分證字號 會員編號 性別 出生年月日 姓名
F234567890 000000002C M 130425 馬00
Y123456789 000000001B M 140316 羅00
F234567890 000000002C M 130425 馬00
.....
.....
.....
U122778899 0000000001 F 121212 堃一芬
S123119999 000000100A M 841010 犇煚囧
E122000111 0000010A0B F 730123 燚燚缕
F123119988 0000003BCA M 841010 囧rz犇
G122113355 0000041GHA M 841010 囧rz鱻靎
===================引 用 shunaaron 文 章===================
如果文檔確認是unicode的話,那先除去編碼問題
可試下TStringList.find('你要找的字串',第幾個指標開始找)
假設有100萬筆資料,分100次去做比對,試看看吧。
第一次給0....之後給10001....20001
可以自己在調看看可以到多少
不過一次應極限應在3萬行...(2^16)猜測
===================引 用 ac910127 文 章===================
感謝大大的回應!!

文字檔內容包含"一些特殊字元",故格式內碼應該為"Unicode"編碼方式存儲
另外小弟使用的Delphi版本為 Delphi2010

請教大大這是否有影響 ?

再次感謝大大的回應!!
===================引 用 shunaaron 文 章===================
tIntIndex:=TStringList.IndexOf('S123456789');
IndexO最後是用PChar來比對,
看一下文字檔格式內碼為何

編輯記錄
ac910127 重新編輯於 2010-11-30 19:37:34, 註解 無‧
ac910127 重新編輯於 2010-11-30 19:44:29, 註解 無‧
shunaaron
高階會員


發表:13
回覆:94
積分:106
註冊:2006-10-06

發送簡訊給我
#10 引用回覆 回覆 發表時間:2010-12-01 11:54:36 IP:123.127.xxx.xxx 訂閱
剛有測試過到10萬多筆還是可以找到,
所以要確認一件事情,當把文字檔讀入TStringList裡時,是將所有資料都讀進去
如:身份字號 姓名等都讀入TStringList裡
如果是這樣的話IndexOf一定會找不到,
因為IndexOf是用完全比對,也就是說你放到TStringList的資料只能是身份字號
不能包含其他資料
另外Find是從你給的指標位子往下開始找到未筆,
剛又測到20萬都可以找到,問題可能出在你讀進來資料,
是只有身份字號或全部資料了

===================引 用 ac910127 文 章===================
感謝大大再次的回覆,並提供建議。

由於不太清楚TStringList.Find 的用法,故在看了下HELP,並根據HELP提供的範例
與大大的建議,寫兩段Code !!

Code 1 - 根據HELP的範例
[code delphi]
procedure TForm1.Button1Click(Sender: TObject);
var
IDList : TStringList;
tIntFund : Integer;
tA: Extended; //紀錄處理時間
begin
IDList:=TStringList.Create;
tA:=Now;
IDList.LoadFromFile('C:\123456.txt');
IDList.Sort; //根據 HELP說明 需要sort
if IDList.Find('0000003BCA',tIntFund) then begin //在1822378的位置
Memo1.Lines.Add(IntToStr(tIntFund)); //有發現時 顯示所在位置
Memo1.Lines.Add(IDList.Strings[tIntFund]); //有發現時 顯示內容
Memo1.Lines.Add(FormatDateTime('HH:NN:SS:ZZZ',Now-tA)); //顯示處理時間
end;
IDList.Free;
end;
[/code]

Code 2 - 根據大大的建議
[code delphi]
procedure TForm1.Button2Click(Sender: TObject);
var
IDList : TStringList;
tIntFund : Integer;
tA: Extended;
begin
IDList:=TStringList.Create;
tA:=Now;
IDList.LoadFromFile('C:\123456.txt');
IDList.Sort;
tIntFund:=0;
while tIntFund > IDList.Count do begin
if IDList.Find('0000003BCA',tIntFund) then begin //在1822378的位置
Memo1.Lines.Add(IDList.Strings[tIntFund]); //有發現時 顯示內容
Memo1.Lines.Add(FormatDateTime('HH:NN:SS:ZZZ',Now-tA)); //顯示處理時間
break;
end else begin
Inc(tIntFund,30000); //沒有發現時,起始位置加三萬
end;
end;
IDList.Free;
end;
[/code]
以上兩種方式均無法找到。不知是小弟哪邊錯誤了!!!

另外,TStrginList.Find 是否是從Index的位置開始搜尋 到 最尾端??
還是 ??
煩請大大再次為小弟解惑 !!

再次感謝大大的回覆 !!


PS:本來想上傳ID對照檔,可是小弟好像沒辦法上傳檔案了,以下提供ID對照表格式
身分證字號 會員編號 性別 出生年月日 姓名
F234567890 000000002C M 130425 馬00
Y123456789 000000001B M 140316 羅00
F234567890 000000002C M 130425 馬00
.....
.....
.....
U122778899 0000000001 F 121212 堃一芬
S123119999 000000100A M 841010 犇煚囧
E122000111 0000010A0B F 730123 燚燚缕
F123119988 0000003BCA M 841010 囧rz犇
G122113355 0000041GHA M 841010 囧rz鱻靎
===================引 用 shunaaron 文 章===================
如果文檔確認是unicode的話,那先除去編碼問題
可試下TStringList.find('你要找的字串',第幾個指標開始找)
假設有100萬筆資料,分100次去做比對,試看看吧。
第一次給0....之後給10001....20001
可以自己在調看看可以到多少
不過一次應極限應在3萬行...(2^16)猜測
===================引 用 ac910127 文 章===================
感謝大大的回應!!

文字檔內容包含"一些特殊字元",故格式內碼應該為"Unicode"編碼方式存儲
另外小弟使用的Delphi版本為 Delphi2010

請教大大這是否有影響 ?

再次感謝大大的回應!!
===================引 用 shunaaron 文 章===================
tIntIndex:=TStringList.IndexOf('S123456789');
IndexO最後是用PChar來比對,
看一下文字檔格式內碼為何

------
程式沒有這麼難
只是還沒打通其中要絕
編輯記錄
shunaaron 重新編輯於 2010-11-30 20:55:24, 註解 無‧
mephise
高階會員


發表:4
回覆:149
積分:205
註冊:2004-02-09

發送簡訊給我
#11 引用回覆 回覆 發表時間:2010-12-01 13:29:46 IP:220.130.xxx.xxx 訂閱
您的資料格式是這樣

ex: U122778899 0000000001 F 121212 堃一芬
所以 TStringList 讀取的時候是以"行"為單位的
也就是說

fStringList.IndexOf('U122778899 0000000001 F 121212 堃一芬'); 這樣才會找得到
fStringList.IndexOf('U122778899'); 這樣就會找不到
所以在資料讀取上應該還要做一些手腳, 把欄位分開
所以找不到跟編碼無關 因為你資料有堃這個字, 所以它是 UTF-8 而不是 ANSI, 您用的是2010內定就是 UTF-8, 當然更沒問題了
此外TStringList的上限應該跟String一樣,2G!
------
Mephise Chen
前興德工程師
編輯記錄
mephise 重新編輯於 2010-11-30 22:32:25, 註解 無‧
ac910127
一般會員


發表:7
回覆:27
積分:11
註冊:2009-11-06

發送簡訊給我
#12 引用回覆 回覆 發表時間:2010-12-01 13:37:00 IP:124.219.xxx.xxx 訂閱
感謝大大再次回答並測試 !!

讀進來的資料為全部資料。
大大測試筆數為十萬~二十萬筆,如果大大有空,可否測試資料一百五十萬筆以上 ??

再者,大大說"Find是從你給的指標位子往下開始找到未筆" 這樣是否代表著一定要
從第零筆開始搜尋,因為無法確認"要搜尋的資料在哪個區段",這樣是否跟大大一
開始建議的方式有出入!!! 還是我誤解大大的意思,請大大解惑。

再次感謝大大的回覆!!

===================引 用 shunaaron 文 章===================
剛有測試過到10萬多筆還是可以找到,
所以要確認一件事情,當把文字檔讀入TStringList裡時,是將所有資料都讀進去
如:身份字號 姓名等都讀入TStringList裡
如果是這樣的話IndexOf一定會找不到,
因為IndexOf是用完全比對,也就是說你放到TStringList的資料只能是身份字號
不能包含其他資料
另外Find是從你給的指標位子往下開始找到未筆,
剛又測到20萬都可以找到,問題可能出在你讀進來資料,
是只有身份字號或全部資料了
ac910127
一般會員


發表:7
回覆:27
積分:11
註冊:2009-11-06

發送簡訊給我
#13 引用回覆 回覆 發表時間:2010-12-01 15:13:14 IP:124.219.xxx.xxx 訂閱


感謝大大的回覆!!

大大精闢的解答,讓小弟更加了解TStringList.IndexOf運用。
不過目前正再嘗試 shunaaron 前輩提供"TStringList.Find"進行測試,
由於小弟的資料是百萬筆,導致還是未能找到正確資料。
依舊嘗試中 !!

再次感謝大大的解答。

===================引 用 mephise 文 章===================
您的資料格式是這樣

ex: U122778899 0000000001 F 121212 堃一芬
所以 TStringList 讀取的時候是以"行"為單位的
也就是說

fStringList.IndexOf('U122778899 0000000001 F 121212 堃一芬'); 這樣才會找得到
fStringList.IndexOf('U122778899'); 這樣就會找不到
所以在資料讀取上應該還要做一些手腳, 把欄位分開
所以找不到跟編碼無關 因為你資料有堃這個字, 所以它是 UTF-8 而不是 ANSI, 您用的是2010內定就是 UTF-8, 當然更沒問題了
此外TStringList的上限應該跟String一樣,2G!
編輯記錄
ac910127 重新編輯於 2010-12-01 00:14:47, 註解 無‧
shunaaron
高階會員


發表:13
回覆:94
積分:106
註冊:2006-10-06

發送簡訊給我
#14 引用回覆 回覆 發表時間:2010-12-01 15:13:51 IP:123.127.xxx.xxx 訂閱
看一下紅色字的部份,應是你錯誤的部份了,在看上面ephise
有更清的說明
之前以為TStringList有他的找資料列的大小,
並沒有在往下找就停止比對,
才見意你改成分段模式,
如果是有2G的空間的話,
可以不用使用Find,
直接使用indexof即可
===================引 用 ac910127 文 章===================
感謝大大再次回答並測試 !!

如:身份字號 姓名等都讀入TStringList裡
如果是這樣的話IndexOf一定會找不到,
因為IndexOf是用完全比對,也就是說你放到TStringList的資料只能是身份字號
不能包含其他資料

另外Find是從你給的指標位子往下開始找到未筆,
剛又測到20萬都可以找到,問題可能出在你讀進來資料,
是只有身份字號或全部資料了
------
程式沒有這麼難
只是還沒打通其中要絕
ac910127
一般會員


發表:7
回覆:27
積分:11
註冊:2009-11-06

發送簡訊給我
#15 引用回覆 回覆 發表時間:2010-12-01 15:29:50 IP:124.219.xxx.xxx 訂閱
感謝各位前輩熱心的指導 !!

pprayer前輩 提供以TFileStream方式處理,小弟測試過後,發現
會因長度不固定,而取得非小弟想像中的字串內容,以小弟目前處理上來說,
會有錯誤,故暫不考慮。

感謝shunaaron 前輩 與 mephise前輩再 TStringList上觀念指導,
由於 shunaaron 前輩先指出錯誤點在哪,故此給分給予shunaaron 前輩。

再次感謝前輩們的指導。
編輯記錄
ac910127 重新編輯於 2010-12-01 00:32:09, 註解 無‧
Victor4022
中階會員


發表:0
回覆:76
積分:90
註冊:2011-02-20

發送簡訊給我
#16 引用回覆 回覆 發表時間:2011-02-20 22:29:16 IP:122.126.xxx.xxx 訂閱
您好, 有點晚看到此題目, 不過以下是我的想法:

1. 善用TStringList.Find function, 因為binary search 很有效率, 前提是您的資料必須是要已經排序完畢. 使用IndexOf的話如果資料在第100萬筆時, for loop就必須跑到第100萬次才相符, 如果資料已經先排序後, 使用TStringlist.Find 最\佳情形僅須要1次的代價. 如何實作排序?

[code delphi]
TStringList.LoadFormFile(your file name);
TStringList.Sort;
TStringList.SaveToFile(your sorted file name);
[/code]
這樣下一次使用Find就很快

2. 因為您的資料是由多個欄位組成一行字串而成, 而不管使用IndexOf 或是 Find都是"字串完整"比對, 因此建議您將資料進行欄位切割, 實作2個自訂的object就能達到管理這份200mb的檔案(不過欄位內容請依您的需求進行調整, 以下只是示意程式, 不保證沒bug :P), 例如以下程式:
我用TMyData當成您每一行內的獨立資料, TMyList則容納了您所有的獨立資料, 可以把TMyData想像成一個字串parser, 而程式利用身粉證字號當成TStringList的primary key來使用, 其餘data則利用TMyData這個TObject的其他欄位記下.

[code delphi]
type
TForm1 = class(TForm)
btnTest: TButton;
procedure btnTestClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TMyData = class(TObject)
private
FSn, FName, FAddr : String;
public
property Sn : String read FSn;
property Name : String read FName;
property Addr : String read FAddr;
constructor Create(const RowData : String);
end;
type
TMyList = class(TObject)
private
FCount : Integer;
FList : TStringList;
protected
function FGetMyData(Index: Integer): TMyData;
procedure FPutMyData(Index: Integer; Data: TMyData);
public
property Count : Integer read FCount;
property Data[Index: Integer]: TMyData read FGetMyData write FPutMyData;
function AddData(Data: TMyData) : Integer;
procedure Clear();
procedure Delete(Index: Integer);
function Find(const Sn : String; var FindIndex : Integer) : Boolean;
constructor Create();
destructor Destroy(); override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TMyData }
constructor TMyData.Create(const RowData: String);
var
T : TStringList;
begin
// RowData format : A123456789 小明 台灣省
FSn := '';
FName := '';
FAddr := '';
// extract filed by ' '(space)
T := TStringList.Create;
try
if (ExtractStrings([' '], [' '], PChar(RowData), T) <> 3) then
raise Exception.Create('TMyData rowdata format error.');
FSn := T[0];
FName := T[1];
FAddr := T[2];
finally
T.Free;
end;
end;
{ TMyList }
function TMyList.AddData(Data: TMyData): Integer;
begin
Result :=
FList.AddObject(Data.Sn, Data);
FCount := FList.Count;
end;
procedure TMyList.Clear;
{$IFDEF Delphi2009}
begin
FList.Clear;
{$ELSE}
begin
while (FCount > 0) do
Self.Delete(FCount - 1);
{$ENDIF}
end;
constructor TMyList.Create;
begin
FList := TStringList.Create;
FList.Duplicates := dupAccept;
FList.Sorted := True;
{$IFDEF Delphi2009}
FList.OwnsObjects := True;
{$ENDIF}
end;
procedure TMyList.Delete(Index: Integer);
begin
if (Index > FCount) then Exit;
try
{$IFNDEF Delphi2009}
FList.Objects[Index].Free;
{$ENDIF}
FList.Delete(Index);
except
end;
FCount := FList.Count;
end;
destructor TMyList.Destroy;
begin
FList.Clear;
FList.Destroy;
inherited;
end;
function TMyList.Find(const Sn : String; var FindIndex : Integer) : Boolean;
begin
Result := FList.Find(Sn, FindIndex);
end;
function TMyList.FGetMyData(Index: Integer): TMyData;
begin
Result := FList.Objects[Index] as TMyData;
end;
procedure TMyList.FPutMyData(Index: Integer; Data: TMyData);
begin
FList.Objects[Index] := Data;
end;
{ TForm1 }
procedure TForm1.btnTestClick(Sender: TObject);
var
L: TMyList;
Data : TMyData;
iFind : Integer;
sFindSn : String;
begin
sFindSn := 'B123456790';
L := TMyList.Create;
try
L.AddData(TMyData.Create('A123456789 小明1 台灣省1'));
L.AddData(TMyData.Create('C123456791 小明3 台灣省3'));
L.AddData(TMyData.Create('B123456790 小明2 台灣省2'));
if L.Find(sFindSn, iFind) then
begin
Data := L.Data[iFind];
ShowMessage(Format('"%s" at idx %d : "%s" "%s" "%s"',
[sFindSn, iFind, Data.Sn, Data.Name, Data.Addr]));
end else
ShowMessage(Format('"%s" not found.', [sFindSn]));
finally
L.Free;
end;
end;
[/code]

3. 另外, 文字檔破100mb, 確實有點大, 像上面幾位前輩所提, 移進database並不是件壞事, 而且查詢速度跟資料維護比較方便.

4. 最後, 您這檔案內應該都是重要的個人資料, 台灣個資法已經通過了, 提醒您要小心使用啊!!!~~~


Victor4022
中階會員


發表:0
回覆:76
積分:90
註冊:2011-02-20

發送簡訊給我
#17 引用回覆 回覆 發表時間:2011-02-20 22:37:54 IP:122.126.xxx.xxx 訂閱
您好, 再補充一點, 剛剛看了Delphi 7的原始碼, TStringList 清單上限如下:

[code delphi]
unit Classes;
...
...
...
{ Maximum TList size }
MaxListSize = Maxint div 16;
...
...
{ TStringList class }

TStringItemList = array[0..MaxListSize] of TStringItem;
[/code]

應該可以儲存到9位數字, 大約1億3千多萬筆:)

ac910127
一般會員


發表:7
回覆:27
積分:11
註冊:2009-11-06

發送簡訊給我
#18 引用回覆 回覆 發表時間:2011-02-21 10:30:56 IP:59.126.xxx.xxx 訂閱
感謝 Victor4022 大大熱心的回答 !!

讓小弟在學到一種方法。

也感謝大大的個資法的提醒@@

那是虛擬資料,並非真實個資,應該沒有違法吧!!!

再次謝謝大大 !!


===================引 用 Victor4022 文 章===================
您好, 再補充一點, 剛剛看了Delphi 7的原始碼, TStringList 清單上限如下:

[code delphi]
unit Classes;
...
...
...
{ Maximum TList size }
MaxListSize = Maxint div 16;
...
...
{ TStringList class }

TStringItemList = array[0..MaxListSize] of TStringItem;
[/code]

應該可以儲存到9位數字, 大約1億3千多萬筆:)

系統時間:2024-08-15 6:28:40
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!