Autor |
Beitrag |
Siluro
      
Beiträge: 74
Win XP Prof., Win XP64 Prof., Win 7 Prof.
Delphi 7 Ent., Delphi XE, Delphi XE5
|
Verfasst: Do 04.06.15 17:23
Hi Leute,
ich habe ein merkwürdiges Problem in meiner Anwendung in Delphi XE5. Eine Funktion gibt mir einen extrem langen String zurück. Den Rückgabewert schreibe ich in die Text-Property eines Edit-Feldes. Zur Laufzeit bleibt das Feld in der Anzeige jetzt aber komischerweise leer, während Text beim Debuggen aber gefüllt ist.
Das Gleich passiert, wenn ich den Wert Label.Caption zuweise. Beim Versuch den Rückgabewert an ein Memo zu übergeben, friert sogar das komplette Programm ein (ohne Fehlermeldung).
Bei Google hab ich leider nichts gefunden (oder einfach nicht die richtigen Worte gefunden). Hat hier vielleicht jemand ne Idee?
Schon mal vielen Dank im Voraus.
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Do 04.06.15 18:42
Hallo,
gibt doch einfach mal die Länge aus/an, damit man das abschäten kann, was da schief geht.
EIn Memo braucht viel Zeit um alle Zeilen daraus zu extrahieren.
Gruß Horst
|
|
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Do 04.06.15 19:49
|
|
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Do 04.06.15 20:43
|
|
Siluro 
      
Beiträge: 74
Win XP Prof., Win XP64 Prof., Win 7 Prof.
Delphi 7 Ent., Delphi XE, Delphi XE5
|
Verfasst: Fr 05.06.15 09:48
Moin,
erstmal danke für die Rückmeldungen. Vielleicht muss ich dann doch ein bisschen weiter ausholen. Bei meinem Projekt handelt es sich um einen WYSIWYG-Designer. Dafür benutze ich die Vektor-Komponente von ImageEn und male mir Bilder auf die Zeichenfläche. Diesen Platzhaltern sollen dann Inhalte zugewiesen werden (Bilder, Videos, RTF-Text). Bilder und Videos lasse ich mal außen vor, da hier keine Probleme auftreten.
Für RTF-Text benutze ich die WPTools und lasse mir den Inhalt dann als String ausgeben. Das war bisher auch kein Problem. Allerdings ist nun die Anforderung hinzugekommen, dass im RTF-Text Bilder enthalten sein können. So komme ich also zu meinen ewig langen Strings (6 – 7 Stellig).
Die entscheidenden Stellen im Code sehen dann Folgendermaßen aus:
RichText Inhalt auslesen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| case pcDialogs.ActivePageIndex of 0: FResult := edImageFileName.Text; 1: FResult := edVideoFileName.Text; 2: begin DeletePages; FResult := string(rtContent.AsANSIString('RTF-nobinary')); end; end; |
Inhalt an Hauptformular zurückgeben:
Delphi-Quelltext 1: 2: 3: 4:
| function TfrmContentDlg.GetResult: string; begin Result := FResult; end; |
Und hier der Code vom Hauptformular:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| if ContentDlg.ShowModal = mrOk then begin edContent.Text := ContentDlg.GetResult; label1.Caption := AnsiReplaceStr(edContent.Text, #13#10, ''); text := edContent.Text; showmessage(inttostr(length(ContentDlg.GetResult))); showmessage(inttostr(length(edContent.Text))); showmessage(inttostr(length(label1.Caption))); showmessage(inttostr(length(trim(label1.Caption)))); application.ProcessMessages; if LoadContent(ievArea.SelObjects[0] ,ievArea.ObjID[ievArea.SelObjects[0]], edContent.Text) then try except on e:exception do showmessage(e.Message); end; end; |
Kurz zu den Fragen von Perlsau:
Perlsau hat folgendes geschrieben : | Welchem Zweck sollte es dienen, einen String anzeigen zu wollen, der ob seiner Länge niemals vollständig angezeigt werden kann? |
Es geht nur darum dass das Feld nicht leer ist (wäre für den Benutzer wohl ganz schön verwirrend)
Perlsau hat folgendes geschrieben : | Wie hast du überprüft, ob das Edit-Feld bzw. die Label-Caption leer bleiben? |
Weil kein Inhalt angezeigt wird.
Die Memo-Fragen überspringe ich mal, da ich die Komponente eigentlich nicht verwenden möchte. Hatte das nur zum Testen mal verwendet.
Perlsau hat folgendes geschrieben : | Wie lang ist er String? |
Die Länge des Strings liegt halt im oberen 6-stelligen bis untern 7-stelligen Bereich.
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Fr 05.06.15 10:07
Hallo,
lass mal auf die Schnelle AnsiStringReplace weg und teste dann die Laufzeit.
Für Deinen speziellen Fall, wo 2 Zeichen durch etwas kürzeres ersetzt werden, kann man eventuell schneller vorgehen.
Gruß Horst
EIn String mit 10e6 Zeichen war in 330 Sekunden noch nicht fertig.
ein String mit 1e6 Zeichen war in 1,5 Sekunden fertig.
|
|
Siluro 
      
Beiträge: 74
Win XP Prof., Win XP64 Prof., Win 7 Prof.
Delphi 7 Ent., Delphi XE, Delphi XE5
|
Verfasst: Fr 05.06.15 12:05
Sorry für die Verzögerung. Ich bin gerade dabei mich um das Problem mit dem Freeze zu kümmern und wollte mal versuchen das über einen Pointer zu lösen. Dabei hatte ich unter anderem folgenden Code:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| sContent := ContentDlg.GetResult; if (ievArea.ObjID[hObj] = 2) and (Length(sContent) > 200) then begin edContent.Text := copy(sContent, 1, 200); ievArea.ObjUserData[hObj] := @sContent; end else edContent.Text := sContent; label1.Caption := string(ievArea.ObjUserData[hObj]^);
showmessage(inttostr(length(ContentDlg.GetResult))); showmessage(inttostr(length(label1.Caption))); showmessage(inttostr(length(trim(label1.Caption)))); application.ProcessMessages; |
Wenn ich Label1.Caption über den Pointer hole, wird es mir auf dem Formular angezeigt. Verstehe nur nicht, wo der Unterschied ist.
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Fr 05.06.15 12:40
Hallo,
wie denn? Wo denn? Was denn?
Einmal willst 10e6 Byte mit replaceString beackern, das andere mal beschränkst Du Dich auf 200 Byte.
Hast Du vielleicht das Edit nicht gesehen?
Zitat: | EIn String mit 10e6 Zeichen war in 330 Sekunden noch nicht fertig.
ein String mit 1e6 Zeichen war in 1,5 Sekunden fertig. |
Gruß Horst
Ein kleines Test Programm mit einem alternativem Replacestring aus www.delphipraxis.net/457239-post1.html für eine 10 Mio Zeichen String, mit CRLF alle 60 Zeichen aka 166666 Zeilen mit einem Rest.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185:
| program test; {$MODE DELPHI} uses sysutils, strutils;
const gesLen = 10*1000*1000; rowLen = 60; var s : AnsiString; p : longInt;
function StringReplaceMultiple(const Source: AnsiString; const OldPatterns, NewPatterns: array of AnsiString; CaseSensitive: Boolean = True): AnsiString;
type TFoundPos = record Position: Integer; PatternNum: Integer; end;
var C: Integer; FoundCount: Integer; SourcePosition: Integer; PatternCount: Integer; Positions: array of TFoundPos; PositionLength: Integer;
PatternNum: Integer; SourceLength: Integer; OldLengths, NewLengths: array of Integer; DeltaOld: Integer;
Delta: Integer;
PSource, PDest, PNew: PAnsiChar;
SearchSource: AnsiString; CasePatterns: array of AnsiString;
begin if (Source = '') or (Length(OldPatterns) <> Length(NewPatterns)) then begin Result := Source; Exit; end;
try PatternCount := Length(OldPatterns); SourceLength := Length(Source); SetLength(OldLengths, PatternCount); SetLength(NewLengths, PatternCount); Delta := 0; DeltaOld := 0; for C := 0 to PatternCount - 1 do begin OldLengths[C] := Length(OldPatterns[C]); NewLengths[C] := Length(NewPatterns[C]); Inc(DeltaOld, OldLengths[C]); end; DeltaOld := Round(DeltaOld / PatternCount);
SetLength(CasePatterns, PatternCount); if CaseSensitive then begin SearchSource := Source; for C := 0 to PatternCount - 1 do CasePatterns[C] := OldPatterns[C]; end else begin SearchSource := AnsiLowerCase(Source); for C := 0 to PatternCount - 1 do CasePatterns[C] := AnsiLowerCase(OldPatterns[C]); end;
FoundCount := 0;
PositionLength := SourceLength div DeltaOld + 1; SetLength(Positions, PositionLength);
C := 1; while C <= SourceLength do begin for PatternNum := 0 to PatternCount - 1 do begin if (SearchSource[C]) = (CasePatterns[PatternNum][1]) then begin if CompareMem(@SearchSource[C], @CasePatterns[PatternNum][1], OldLengths[PatternNum]) then begin if FoundCount >= PositionLength then begin Inc(PositionLength, 4); SetLength(Positions, PositionLength); end;
Positions[FoundCount].Position := C; Positions[FoundCount].PatternNum := PatternNum; Inc(FoundCount); Inc(C, OldLengths[PatternNum] - 1); Inc(Delta, NewLengths[PatternNum] - OldLengths[PatternNum]); Break; end; end; end; Inc(C); end;
SetLength(CasePatterns, 0);
if FoundCount > 0 then begin SetLength(Result, SourceLength + Delta);
SourcePosition := 1; PSource := PAnsiChar(Source); PDest := PAnsiChar(Result);
for C := 0 to FoundCount - 1 do begin PNew := PAnsiChar(NewPatterns[Positions[C].PatternNum]);
Move(PSource^, PDest^, Positions[C].Position - SourcePosition); Inc(PDest, Positions[C].Position - SourcePosition);
Move(PNew^, PDest^, NewLengths[Positions[C].PatternNum]); Inc(PDest, NewLengths[Positions[C].PatternNum]);
Inc(PSource, Positions[C].Position - SourcePosition + OldLengths[Positions[C].PatternNum]); SourcePosition := Positions[C].Position + OldLengths[Positions[C].PatternNum]; end;
Move(PSource^, PDest^, SourceLength - SourcePosition + 1); end else Result := Source; Finalize(Positions); except end; end; var Pat,Rpl : array of AnsiString; Begin setlength(s,gesLen); fillchar(s[1],length(s),'A'); p := (length(s) DIV rowLen) *rowLen-1; while p > 2 do begin s[p]:= #13; s[p+1]:= #10; dec(p,60); end; setlength(Pat,1); setlength(Rpl,1); Pat[0] := #13#10; Rpl[0] := ' ';
writeln(length(s)); s:=StringReplaceMultiple(s,Pat,Rpl); writeln(length(s)); end. |
Laufzeit bei mir 66ms.
Quelltext 1: 2: 3: 4: 5: 6:
| 10000000 9833334
real 0m0.066s user 0m0.062s sys 0m0.003s |
|
|
|