TStringList -> SaveToFile() 可存的檔案大小 |
答題得分者是:Victor4022
|
sussy
一般會員 發表:2 回覆:7 積分:1 註冊:2010-10-15 發送簡訊給我 |
|
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
|
sussy
一般會員 發表:2 回覆:7 積分:1 註冊:2010-10-15 發送簡訊給我 |
for(i=0;i 您好,我是要 training 一大筆的資料,目的是要在所有資料中記錄單字和單字搭配的資數 記錄在int 宣告的7204x7204的二維動態陣列中。 然後轉成txt檔記錄。 問題是,要是training的資料放的少,就不會有此問題 如果training的資料太多就會在 " Output->SaveToFile("WordPairFreq.txt"); " 請各位先進解惑,謝謝 |
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
可能是前面的物件沒有釋放吧
以下程式碼請試試看 [code cpp] //---------------------統計------------------------- TStringList *FileList = new TStringList(); TStringList *TSL1 = new TStringList(); TStringList *TSL2 = new TStringList(); for (i = 0; i < this->FileListBox1->Count; i ) { FileList->LoadFromFile(this->FileListBox1->Items->Strings[i]); this->CGauge2->MaxValue = FileList->Count; this->CGauge2->MinValue = 0; this->CGauge2->Progress = 0; for (j = 0; j < FileList->Count; j ) { TSL1->Text = FileList->Strings[j]; TSL1->Delimiter = ' '; TSL1->DelimitedText = FileList->Strings[j]; for (k = 0; k < TSL1->Count; k ) { AnsiString test132 = TSL1->Strings[k]; if (TSL1->Strings[k] == "《民生報》" && (k 3) < TSL1->Count) { //遇到標題,後二筆不記錄 k = k 3; } if (TSL1->Strings[k] != "") { // AnsiString AS1 = TSL1->Strings[k]; TStringList *SSentence = new TStringList(); SSentence = SegmentSentence(AS1); for (l = 0; l < SSentence->Count; l ) { TSL2->Text = SSentence->Strings[l]; TSL2->Delimiter = ' '; TSL2->DelimitedText = SSentence->Strings[l]; for (n = 0; n < TSL2->Count; n ) { AnsiString AS2 = TSL2->Strings[n]; for (m = 1; m <= AS2.Length(); m = 2) { if (OnlyWord.Pos(AS2.SubString(m, 2)) > 0) { //若有字典裡的單字則記錄單字頻率,否則不記錄 AnsiString test112 = AS2.SubString(m, 2); AnsiString test158 = AS2.SubString(m 2, 2); int OW_index1 = OnlyWord.Pos(AS2.SubString(m, 2)); int OW_index2 = OnlyWord.Pos(AS2.SubString(m 2, 2)); if (OW_index2 != 0 && (OW_index1 % 2 == 0 || OW_index2 % 2 == 0) ) { OW_index1 = POSMine(AS2.SubString(m, 2)); OW_index2 = POSMine(AS2.SubString(m 2, 2)); } OW_index1 = (OW_index1 1) / 2; OW_index2 = (OW_index2 1) / 2; WordPairFreq[OW_index1][0] ; //記錄單字頻率 if ((m 2) <= AS2.Length()) { WordPairFreq[OW_index1][OW_index2] ; //記錄單字搭配頻率 } } } } TSL2->Clear(); } } } TSL1->Clear(); this->CGauge2->Progress ; } FileList->Clear(); this->CGauge1->Progress ; } delete FileList; delete TSL1; delete TSL2; //------------------------------------------------------------ //---------------------儲存陣列的資料------------------------- this->CGauge3->MaxValue = 7204 * 7204; this->CGauge3->MinValue = 0; this->CGauge3->Progress = 0; TStringList *Output = new TStringList(); AnsiString ANS1 = ""; for (i = 1; i < 7205; i ) { int CT1 = 0; for (j = 0; j < 7205; j ) { ANS1 = ANS1 FloatToStr(WordPairFreq[i][j]) " "; CT1 = CT1 1; if (CT1 % 55 == 0) { Output->Add(ANS1); ANS1 = ""; CT1 = 0; } this->CGauge3->Progress ; } } //------------------------------------------------------------- for (int i = 0; i < 7205; i ) { delete [] WordPairFreq[i]; } delete [] WordPairFreq; Output->SaveToFile("WordPairFreq.txt"); [/code] |
sussy
一般會員 發表:2 回覆:7 積分:1 註冊:2010-10-15 發送簡訊給我 |
|
Victor4022
中階會員 發表:0 回覆:76 積分:90 註冊:2011-02-20 發送簡訊給我 |
您好,如果已確認是 TStringList.SaveToFile 造成 out of memory 的話,
建議您可以選擇分批儲存至檔案,像是建立 TFileStream ,例用 for 迴圈串起 TStringList 的部份內容, 每串起 10 行就寫出至 TFileStream 一次,這樣就不會增加額外記憶體。 PS. 所謂"額外記憶體",指的是 TStringList.SaveToFile內的實作方式,會讓記憶增加一倍,因為底下這些程式碼: [code delphi] procedure TStrings.SaveToStream(Stream: TStream); var S: string; begin S := GetTextStr; Stream.WriteBuffer(Pointer(S)^, Length(S)); end;[/code] |
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
你的陣列光是宣告就占了很大的記憶體了(7204 *7204)
我的機器到這一行就Out of Memory了 剛看到這個網站,這個解法不錯,但僅限Delphi才可使用 http://www.websnap123.com/show-TnpReE9EUTI=.html TMemoryStream也可以解決你的問題,站上好像有分割存檔的帖子,請你再搜搜看看 以上 ===================引 用 sussy 文 章=================== 您好,我照您的方法試過了,但遇到一次大量的文章還是會產生"out of memory" 的錯誤。 |
sussy
一般會員 發表:2 回覆:7 積分:1 註冊:2010-10-15 發送簡訊給我 |
V大您好,我試過您建議的方法,但我不知道如何使用將所有字串存在同一個檔裡 ,
我使用"fmOpenReadWrite",無法再重新寫入同一個檔。 沒寫過,請幫我看看程式那裡不妥。謝謝 AnsiString char file1[] = "test.txt"; TSF_test->Write(filedata.c_str(),filedata.Length()); }TSF_test->Free(); ===================引 用 Victor4022 文 章=================== 您好,如果已確認是 TStringList.SaveToFile 造成 out of memory 的話, 建議您可以選擇分批儲存至檔案,像是建立 TFileStream ,例用 for 迴圈串起 TStringList 的部份內容, 每串起 10 行就寫出至 TFileStream 一次,這樣就不會增加額外記憶體。 PS. 所謂"額外記憶體",指的是 TStringList.SaveToFile內的實作方式,會讓記憶增加一倍,因為底下這些程式碼: [code delphi] procedure TStrings.SaveToStream(Stream: TStream); var S: string; begin S := GetTextStr; Stream.WriteBuffer(Pointer(S)^, Length(S)); end;[/code] |
sussy
一般會員 發表:2 回覆:7 積分:1 註冊:2010-10-15 發送簡訊給我 |
G大您好,
因為7204x7204無宣告成靜態,所以我宣告動態。 是需先儲成txt檔方便之後讀檔直接取出需要的資料。 在記憶體方面沒有碰過,我嘗試分成幾個檔儲存,但當資料大還是會發是錯誤。 謝謝您的建議,我爬文找看看其他方法。 ===================引 用 GrandRURU 文 章=================== 你的陣列光是宣告就占了很大的記憶體了(7204 *7204) 我的機器到這一行就Out of Memory了 剛看到這個網站,這個解法不錯,但僅限Delphi才可使用 http://www.websnap123.com/show-TnpReE9EUTI=.html TMemoryStream也可以解決你的問題,站上好像有分割存檔的帖子,請你再搜搜看看 以上 ===================引 用 sussy 文 章=================== 您好,我照您的方法試過了,但遇到一次大量的文章還是會產生"out of memory" 的錯誤。 |
Victor4022
中階會員 發表:0 回覆:76 積分:90 註冊:2011-02-20 發送簡訊給我 |
您好, 以下是我的想法:
[code delphi] procedure TForm1.FormCreate(Sender: TObject); var I : Integer; FileList : TStringList; SavedFileStream : TFileStream; sTmp : AnsiString; begin FileList := TStringList.Create; FileList.LoadFromFile(FileListBox1.Items.Strings[1]); // 先建立 FileStream SavedFileStream := TFileStream.Create('c:\text', fmCreate); try // 開始處理 FileList 內容 sTmp := ''; for I :=0 to FileList.Count -1 do begin sTmp := sTmp FileList.Strings[I]; if ((I MOD 10) = 0) then // 每隔 10 行寫入至檔案一次 begin SavedFileStream.Write(sTmp[1], Length(sTmp)); sTmp := ''; end; end; // for I end if (Length(sTmp) > 0) then SavedFileStream.Write(sTmp[1], Length(sTmp)); finally FileList.Free; SavedFileStream.Free; end; end; [/code] 真抱歉, 我居然用 Delphi 程式回覆您, 您應該很困擾吧!! ===================引 用 sussy 文 章=================== V大您好,我試過您建議的方法,但我不知道如何使用將所有字串存在同一個檔裡 , 我使用"fmOpenReadWrite",無法再重新寫入同一個檔。 沒寫過,請幫我看看程式那裡不妥。謝謝 AnsiString char file1[] = "test.txt"; TSF_test->Write(filedata.c_str(),filedata.Length()); }TSF_test->Free(); ===================引 用 Victor4022 文 章=================== 您好,如果已確認是 TStringList.SaveToFile 造成 out of memory 的話, 建議您可以選擇分批儲存至檔案,像是建立 TFileStream ,例用 for 迴圈串起 TStringList 的部份內容, 每串起 10 行就寫出至 TFileStream 一次,這樣就不會增加額外記憶體。 PS. 所謂"額外記憶體",指的是 TStringList.SaveToFile內的實作方式,會讓記憶增加一倍,因為底下這些程式碼: [code delphi] procedure TStrings.SaveToStream(Stream: TStream); var S: string; begin S := GetTextStr; Stream.WriteBuffer(Pointer(S)^, Length(S)); end;[/code]
編輯記錄
Victor4022 重新編輯於 2011-11-19 05:34:03, 註解 無‧
|
sussy
一般會員 發表:2 回覆:7 積分:1 註冊:2010-10-15 發送簡訊給我 |
您好,您肯花時間替我解惑,就很幫我忙了,謝謝。
謝謝您的建議,問題已經可以解決了!感謝! ===================引 用 Victor4022 文 章=================== 您好, 以下是我的想法: [code delphi] procedure TForm1.FormCreate(Sender: TObject); var I : Integer; FileList : TStringList; SavedFileStream : TFileStream; sTmp : AnsiString; begin FileList := TStringList.Create; FileList.LoadFromFile(FileListBox1.Items.Strings[1]); // 先建立 FileStream SavedFileStream := TFileStream.Create('c:\text', fmCreate); try // 開始處理 FileList 內容 sTmp := ''; for I :=0 to FileList.Count -1 do begin sTmp := sTmp FileList.Strings[I]; if ((I MOD 10) = 0) then // 每隔 10 行寫入至檔案一次 begin SavedFileStream.Write(sTmp[1], Length(sTmp)); sTmp := ''; end; end; // for I end if (Length(sTmp) > 0) then SavedFileStream.Write(sTmp[1], Length(sTmp)); finally FileList.Free; SavedFileStream.Free; end; end; [/code] 真抱歉, 我居然用 Delphi 程式回覆您, 您應該很困擾吧!! |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |