|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Утечка памяти out of memory
Добрый день, уважаемые пользователи.
Суть проблемы: При запуске процедуры идет работа в файле размеров в .... мегабайт. И после 5 секунд выскакивает окно out of memory. Хотя файлы до 200 мегабайт нормально. Я так понял что это из за недостатка выделенной памяти на массив, строку. Какие ошибки допущены в коде и как решить эту проблему? Код:
procedure Tfrm_Main.Run; var afList: TStringDynArray; i, j, k: integer; L, rL, fL: TStringList; NewName, tmp: String; begin memo_Log.Lines.Add(Format('Начало обработки: %s', [DateTimeToStr(Now)])); memo_Log.Lines.Add('///'); memo_Log.Lines.Add(''); L := TStringList.Create; for i := 0 to memo_Folders.Lines.Count - 1 do begin afList := TDirectory.GetFiles(memo_Folders.Lines[i], '*.txt', SO); for j := 0 to Length(afList) - 1 do L.Add(afList[j]); end; rL := TStringList.Create; rL.Text := Trim(memo_List.Text); k := 0; fL := TStringList.Create; for i := 0 to L.Count - 1 do begin memo_Log.Lines.Add(Format('Обработка файлов %s', [L.Strings[i]])); fL.LoadFromFile(L.Strings[i]); tmp := ExtractFileName(L.Strings[i]); tmp := Copy(tmp, 1, Pos('.', tmp) - 1); NewName := Format('%s%s.%s', [ExtractFilePath(L.Strings[i]), tmp, FormatDateTime('ddmmyy_hhnn', Now)]); if rg_Order.ItemIndex = 1 then for j := 0 to rL.Count - 1 do rL.Exchange(j, RandomRange(0, rL.Count)); for j := 0 to fL.Count - 1 do begin fL.Strings[j] := StringReplace(fL.Strings[j], edt_Word.Text, rL.Strings[k], RF); inc(k); if k = rL.Count then k := 0; end; fL.SaveToFile(NewName); memo_Log.Lines.Add(Format('Сохранение под именем %s', [NewName])); memo_Log.Lines.Add(''); end; memo_Log.Lines.Add('///'); memo_Log.Lines.Add(Format('Окончание обработки: %s', [DateTimeToStr(Now)])); fL.Free; rL.Free; L.Free; btn_Next.Enabled := false; LoadBMP(btn_Prev, 5); btn_Prev.Caption := 'С начала'; end; Последний раз редактировалось Taras2020, 31.01.2018 в 12:48. |
#2
|
|||
|
|||
Ну, убивать, в смысле руки отрывать, за такое надо.
Ты же все-равно делаешь замену в рамках одной строки. Ну так нафига читать файл целиком? Читай по одной строке. Что-то типа: Код:
procedure ReplaceSubStringInFile(ASrcFileName, ATgtFileName, ASrcStr, ATgtStr : String); var F_Src, F_Tgt : TextFile; S : String; begin AssignFile(F_Src,ASrcFileName); AssingFile(F_Tgt,ATgtFileName); Reset(F_Src); Reqwrite(F_Tgt); While Not EOF(F_Src) Do Begin ReadLN(F_Src,S); S := StringReplace(S,ASrcStr,ATgtStr,[srReplaceAll]); WriteLn(F_Tgt,S); End; CloseFile(F_Src); CloseFile(F_Tgt); end; |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
Taras2020 (30.01.2018)
|
#3
|
|||
|
|||
Цитата:
|
#4
|
||||
|
||||
Цитата:
Грамотно поставленный вопрос содержит не менее 50% ответа. Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть. |
Этот пользователь сказал Спасибо dr. F.I.N. за это полезное сообщение: | ||
Taras2020 (31.01.2018)
|
#5
|
|||
|
|||
Цитата:
|
#6
|
||||
|
||||
Не стал разбираться досконально с кодом, но что-то такое должно получится. Imikle все и так написал.
Код:
procedure Tfrm_Main.Run; var afList: TStringDynArray; i, j, k: integer; L, rL{, fL}: TStringList; NewName, tmp: String; //==== F_Src, F_Tgt : TextFile; S : String; begin memo_Log.Lines.Add(Format('Начало обработки: %s', [DateTimeToStr(Now)])); memo_Log.Lines.Add('///'); memo_Log.Lines.Add(''); L := TStringList.Create; for i := 0 to memo_Folders.Lines.Count - 1 do begin afList := TDirectory.GetFiles(memo_Folders.Lines[i], '*.txt', SO); for j := 0 to Length(afList) - 1 do L.Add(afList[j]); end; rL := TStringList.Create; rL.Text := Trim(memo_List.Text); k := 0; //fL := TStringList.Create; for i := 0 to L.Count - 1 do begin memo_Log.Lines.Add(Format('Обработка файлов %s', [L.Strings[i]])); //fL.LoadFromFile(L.Strings[i]); AssignFile(F_Src,L.Strings[i]); Reset(F_Src); tmp := ExtractFileName(L.Strings[i]); tmp := Copy(tmp, 1, Pos('.', tmp) - 1); NewName := Format('%s%s.%s', [ExtractFilePath(L.Strings[i]), tmp, FormatDateTime('ddmmyy_hhnn', Now)]); AssingFile(F_Tgt,NewName); Rewrite(F_Tgt); if rg_Order.ItemIndex = 1 then for j := 0 to rL.Count - 1 do rL.Exchange(j, RandomRange(0, rL.Count)); While Not EOF(F_Src) Do Begin ReadLN(F_Src,S); S := StringReplace(S, edt_Word.Text, rL.Strings[k], RF); WriteLn(F_Tgt,S); inc(k); if k = rL.Count then k := 0; End; // for j := 0 to fL.Count - 1 do //begin //fL.Strings[j] := StringReplace(fL.Strings[j], edt_Word.Text, rL.Strings[k], RF); //inc(k); //if k = rL.Count then k := 0; //end; //fL.SaveToFile(NewName); CloseFile(F_Src); CloseFile(F_Tgt); memo_Log.Lines.Add(Format('Сохранение под именем %s', [NewName])); memo_Log.Lines.Add(''); end; memo_Log.Lines.Add('///'); memo_Log.Lines.Add(Format('Окончание обработки: %s', [DateTimeToStr(Now)])); //fL.Free; rL.Free; L.Free; btn_Next.Enabled := false; LoadBMP(btn_Prev, 5); btn_Prev.Caption := 'С начала'; end; Кстати, есть полезная функция - ExtractFileExt Грамотно поставленный вопрос содержит не менее 50% ответа. Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть. Последний раз редактировалось dr. F.I.N., 31.01.2018 в 11:43. |
Этот пользователь сказал Спасибо dr. F.I.N. за это полезное сообщение: | ||
Taras2020 (31.01.2018)
|
#7
|
|||
|
|||
Цитата:
Последний раз редактировалось Taras2020, 31.01.2018 в 12:22. |
#8
|
|||
|
|||
на самом деле зря вставил код в существующий. Я же не зря написал отдельную процку, просто ее надо было использовать, а то теперь получился размазанный по всей процедуре код.
Кстати, вот меня смущает такая строка: Код:
if k = rL.Count then k := 0; И еще. Если у тебя много файлов, да еще и больших, то я бы подумал на тему написания многопоточного приложения. |
#9
|
||||
|
||||
Цитата:
Код:
While Not EOF(F_Src) Do Begin ReadLN(F_Src,S); S := StringReplace(S, edt_Word.Text, rL.Strings[k], RF); //<-----rL.Strings[k] WriteLn(F_Tgt,S); inc(k); if k = rL.Count then k := 0; End; Грамотно поставленный вопрос содержит не менее 50% ответа. Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть. |
#10
|
||||
|
||||
Цитата:
4250 Помогаю платно. Помогаю иногда бесплатно. |
#11
|
|||
|
|||
Цитата:
Да бред какой-то получается. Надо точно знать задачу. Что-то там точно не просто так. |
#12
|
||||
|
||||
Цитата:
Грамотно поставленный вопрос содержит не менее 50% ответа. Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть. |
#13
|
||||
|
||||
Цитата:
Грамотно поставленный вопрос содержит не менее 50% ответа. Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть. |
#14
|
|||
|
|||
Ну, я то и написал выше.
А по поводу того, что бред - дык как-то мне не совсем понятен принцип замены. Исходя из размера данных. |
#15
|
||||
|
||||
Цитата:
Грамотно поставленный вопрос содержит не менее 50% ответа. Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть. |