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

讀取文字檔內容,轉換為圖檔,但會有記憶體使用量不斷上升的問題

答題得分者是:william
mnsf
初階會員


發表:104
回覆:90
積分:48
註冊:2003-11-25

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-04-27 11:02:17 IP:220.138.xxx.xxx 未訂閱
各位大大好~~ 我現在利用程式去讀取一些文字檔,文字檔的內容是記錄一些座標值, 我將這些座標值,利用TImage畫出矩形或者三角形,然後再儲存為BMP的圖檔。 我的問題是,因為一個文字檔很大(約1MB),程式讀取多個文字檔(約數十MB)之後,記憶體的使用量會不斷的上升,直到出現"Out of memory"的錯誤訊息為止。不知道我的程式是哪裡出了問題,請各位大大幫幫忙,謝謝。 ps.請將文字檔儲存為*.txt。 程式如下: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, FileCtrl; type TForm1 = class(TForm) Image1: TImage; Button1: TButton; FileListBox1: TFileListBox; procedure decode(source:string;var x1,y1,x2,y2,x3,y3,x4,y4:string); function split(comma,original:string ; index:integer):string; procedure FormShow(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormShow(Sender: TObject); begin filelistbox1.Directory:='c:\test'; end; procedure TForm1.decode(source: string; var x1, y1, x2, y2, x3, y3, x4, y4: string); var temp_source:string; n0,n1:integer; tmpS:string; begin //先計算 , 是否有四個,有的話代表有四組座標 //計算'.'的各數,不可以大於一個 n0:=0; tmpS:=trim(source); while pos(',',tmpS)>0 do begin n1:=pos(',',tmpS); tmpS[n1]:='_'; n0:=n0 1; end; if n0=4 then begin temp_source:=copy(source,3,length(source)-7); //split(',',string,2)是指在string的字串中找出以,為間隔的第2個字串 x1:=split(',',split(' ',temp_source,1),1); y1:=split(',',split(' ',temp_source,1),2); x2:=split(',',split(' ',temp_source,2),1); y2:=split(',',split(' ',temp_source,2),2); x3:=split(',',split(' ',temp_source,3),1); y3:=split(',',split(' ',temp_source,3),2); x4:=split(',',split(' ',temp_source,4),1); y4:=split(',',split(' ',temp_source,4),2); end else begin temp_source:=copy(source,3,length(source)-7); //split(',',string,2)是指在string的字串中找出以,為間隔的第2個字串 x1:=split(',',split(' ',temp_source,1),1); y1:=split(',',split(' ',temp_source,1),2); x2:=split(',',split(' ',temp_source,2),1); y2:=split(',',split(' ',temp_source,2),2); x3:=split(',',split(' ',temp_source,3),1); y3:=split(',',split(' ',temp_source,3),2); x4:=''; y4:=''; end; end; function TForm1.split(comma,original: string; index: integer): string; var //comma:char; original2,divided,sTemp:string; ipos,LengthOrigial:integer; //,myStringListCount ,iposend myStrList:tstringlist; begin try //comma:=' '; //分隔符號,可改成其它如分號,冒號等識別 myStrList:=tstringlist.Create; //myStrList存放分解後字串的地方 original:=original; original2:=original; ipos:=pos(comma,original2); while (ipos<>0) do //當找到分隔符號跳出迴圈 begin original2:=original; ipos:=pos(comma,original2); //ipos為分隔符號所在位置 LengthOrigial:=length(original2); //LengthOrigial為待拆解字串長度 divided:=copy(original2,1,ipos-1); //divided為拆解出字串 myStrList.Add(divided); //將拆解出字串存於myStrList sTemp:=copy(original,ipos 1,LengthOrigial-ipos); //去除掉拆解出字串即分隔符號後的字串 original:=sTemp; //重新交回給original去Run迴圈 end; finally myStrList.Delete(myStrList.Count-1); myStrList.Add(original); //將最後分隔符號 後之字串加入myStrList end; result:=Trim(myStrList.strings[index-1]); end; procedure TForm1.Button1Click(Sender: TObject); var i:integer; F1:Textfile; temp,tmp_filename:string; x1,x2,x3,x4,y1,y2,y3,y4:integer; tmp_struct:string; tmp_x1:string; tmp_y1:string; tmp_x2:string; tmp_y2:string; tmp_x3:string; tmp_y3:string; tmp_x4:string; tmp_y4:string; tmp_shift_x:string; tmp_shift_y:string; begin for i:=0 to filelistbox1.Count-1 do begin //底圖 Image1.Canvas.Brush.Color:=clBtnHighlight; Image1.Canvas.Brush.Style:=bssolid; Image1.Canvas.Polygon([Point(0,0),Point(0,620),Point(620,620),Point(620,0)]); assignfile(F1,'c:\test\' filelistbox1.Items.Strings[i]); Reset(F1); while not eof(F1) do begin Readln(F1,temp); if temp[1]='B' then begin tmp_struct:=''; tmp_x1:=''; tmp_y1:=''; tmp_x2:=''; tmp_y2:=''; tmp_x3:=''; tmp_y3:=''; tmp_x4:=''; tmp_y4:=''; tmp_shift_x:=''; tmp_shift_y:=''; x1:=0; x2:=0; x3:=0; x4:=0; y1:=0; y2:=0; y3:=0; y4:=0; decode(temp,tmp_x1,tmp_y1,tmp_x2,tmp_y2,tmp_x3,tmp_y3,tmp_x4,tmp_y4); if (tmp_x4<>'') and (tmp_y4<>'') then //矩形 begin x1:=round(strtofloat(tmp_x1)*6); y1:=round(620-strtofloat(tmp_y1)*6); x2:=round(strtofloat(tmp_x2)*6); y2:=round(620-strtofloat(tmp_y2)*6); x3:=round(strtofloat(tmp_x3)*6); y3:=round(620-strtofloat(tmp_y3)*6); x4:=round(strtofloat(tmp_x4)*6); y4:=round(620-strtofloat(tmp_y4)*6); Image1.Canvas.Pen.Color:=clred; Image1.Canvas.Brush.Color:=clred; Image1.Canvas.Brush.Style:=bssolid; Image1.Canvas.Polygon([Point(x1,y1),Point(x2,y2),Point(x3,y3),Point(x4,y4)]); end else //三角形 begin x1:=round(strtofloat(tmp_x1)*6); y1:=round(620-strtofloat(tmp_y1)*6); x2:=round(strtofloat(tmp_x2)*6); y2:=round(620-strtofloat(tmp_y2)*6); x3:=round(strtofloat(tmp_x3)*6); y3:=round(620-strtofloat(tmp_y3)*6); Image1.Canvas.Pen.Color:=clred; Image1.Canvas.Brush.Color:=clred; Image1.Canvas.Brush.Style:=bssolid; Image1.Canvas.Polygon([Point(x1,y1),Point(x2,y2),Point(x3,y3)]); end; end; end;//end while closefile(F1); tmp_filename:=copy(filelistbox1.Items.Strings[i],1,pos('.txt',filelistbox1.Items.Strings[i])-1) '.BMP'; image1.Picture.SaveToFile('c:\test\' tmp_filename); end; //end for showmessage('ok'); end; end. 文字檔如下: B 29.124,4.632 32.768,4.632 32.768,23.984 29.124,23.984 ENDB B 0,4.632 28.384,4.632 28.384,23.984 0,23.984 ENDB B 0,0 32.768,0 32.768,1.696 0,1.696 ENDB B 0,0 32.768,0 32.768,32.768 0,32.768 ENDB B 0,0 32.768,0 32.768,32.768 0,32.768 ENDB B 0,13.92 32.768,13.92 32.768,15.028 0,15.028 ENDB B 0,19.436 32.768,19.436 32.768,20.544 0,20.544 ENDB B 0,15.756 32.768,15.756 32.768,16.868 0,16.868 ENDB B 0,17.596 32.768,17.596 32.768,18.708 0,18.708 ENDB B 0,21.284 32.768,21.284 32.768,32.768 0,32.768 ENDB B 0,0 32.768,0 32.768,13.18 0,13.18 ENDB B 0,0 32.768,0 32.768,32.768 0,32.768 ENDB B 0,0 32.768,0 32.768,1.696 0,1.696 ENDB B 29.124,29.832 30.16,29.832 30.16,30.48 29.124,30.48 ENDB B 27.344,29.832 28.384,29.832 28.384,30.48 27.344,30.48 ENDB B 31.028,29.832 32.768,29.832 32.768,30.48 31.028,30.48 ENDB B 0,29.832 26.476,29.832 26.476,30.48 0,30.48 ENDB B 29.192,9.828 32.768,9.828 32.768,10.48 29.192,10.48 ENDB B 0,9.828 28.312,9.828 28.312,10.48 0,10.48 ENDB B 29.124,30.48 30.224,30.48 30.224,32.768 29.124,32.768 ENDB B 27.28,30.48 28.384,30.48 28.384,32.768 27.28,32.768 ENDB B 30.96,30.48 32.768,30.48 32.768,32.768 30.96,32.768 ENDB B 0,30.48 26.544,30.48 26.544,32.768 0,32.768 ENDB B 0,0 32.768,0 32.768,9.828 0,9.828 ENDB B 29.124,10.48 32.768,10.48 32.768,29.832 29.124,29.832 ENDB B 0,10.48 28.384,10.48 28.384,29.832 0,29.832 ENDB B 0,16.86 7.16,16.86 7.16,16.868 0,16.868 ENDB B 0,17.596 7.16,17.596 7.16,17.604 0,17.604 ENDB B 4.376,13.18 4.952,13.18 4.952,13.192 4.376,13.192 ENDB B 4.376,21.272 4.952,21.272 4.952,21.284 4.376,21.284 ENDB B 0,16.8 24.952,16.8 24.952,16.86 0,16.86 ENDB B 0,17.604 24.952,17.604 24.952,17.664 0,17.664 ENDB B 0,13.116 4.952,13.116 4.952,13.18 0,13.18 ENDB B 0,13.92 4.952,13.92 4.952,13.984 0,13.984 ENDB B 0,14.964 4.952,14.964 4.952,15.028 0,15.028 ENDB B 0,15.756 4.952,15.756 4.952,15.82 0,15.82 ENDB B 0,18.644 4.952,18.644 4.952,18.708 0,18.708 ENDB B 0,19.436 4.952,19.436 4.952,19.5 0,19.5 ENDB B 0,20.48 4.952,20.48 4.952,20.544 0,20.544 ENDB B 0,21.284 4.952,21.284 4.952,21.348 0,21.348 ENDB 發表人 - mnsf 於 2004/04/27 11:09:23
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-04-27 11:25:52 IP:147.8.xxx.xxx 未訂閱
Memory leak, you need to free myStringList in function split.
mnsf
初階會員


發表:104
回覆:90
積分:48
註冊:2003-11-25

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-04-27 12:34:05 IP:220.138.xxx.xxx 未訂閱
謝謝william大大,我的問題解決了。 真的當局者迷呀,原來是myStringList沒有free掉,真的是很感謝你。
系統時間:2024-06-26 12:55:43
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!