![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
|||
|
|||
|
Добрый день, уважаемые пользователи.
Суть проблемы: При запуске процедуры идет работа в файле размеров в .... мегабайт. И после 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
|
||||
|
||||
|
Цитата:
|
| Этот пользователь сказал Спасибо 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 Последний раз редактировалось 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; |
|
#10
|
||||
|
||||
|
Цитата:
4250 |
|
#11
|
|||
|
|||
|
Цитата:
Да бред какой-то получается. Надо точно знать задачу. Что-то там точно не просто так. |