AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit speichern einer Stringliste

Ein Thema von Luckie · begonnen am 9. Mär 2004 · letzter Beitrag vom 9. Mär 2004
Antwort Antwort
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

Problem mit speichern einer Stringliste

  Alt 9. Mär 2004, 00:14
Delphi-Quellcode:
function RewriteBookmarkFile(sl: TStrings; Filename: string): Cardinal;
var
  slBookmarkFile: TStringList;
  outerLoop, innerLoop: Cardinal;
  Count: Cardinal;
begin
  Count := 0;
  slBookmarkFile := TStringList.Create;
  try
    slBookmarkFile.LoadFromFile(Filename);
    for outerLoop := 0 to sl.Count - 1 do
    begin
      for innerLoop := slBookmarkFile.Count - 1 downto 0 do
      begin
        if pos(sl.Strings[outerLoop], slBookmarkFile.Strings[innerLoop]) > 0
          then
        begin
          slBookmarkFile.Delete(innerLoop);
          Inc(Count);
        end;
      end;
    end;
    slBookmarkFile.SaveToFile(Filename);
  finally
    FreeAndNil(slBookmarkFile);
  end;
  result := Count;
end;
Warum bekomme ich hier immer zum Schluss den Fehler, dass die Datei nicht erstellt werden könnte?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Problem mit speichern einer Stringliste

  Alt 9. Mär 2004, 00:31
Hmpf. Der Fehler muss wo anders liegen.
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
  sl: TStringList;
  Count: Cardinal;
begin
  sl := TStringList.Create;
  try
    sl.Add('2');
    sl.Add('6');
    sl.Add('4');
    sl.Add('7');
    Count := RewriteBookmarkFile(sl, ExtractFilepath(ParamStr(0))+'test.txt');
  finally
    FreeAndNil(sl);
  end;
end;
Mit diesem Aufruf geht es tadellos.

Aber hier nicht:
Delphi-Quellcode:
procedure TForm1.btnNextClick(Sender: TObject);
var
  AllowChange: Boolean;
  sl: TStringList;
  Loop: Cardinal;
  pidl: PItemIDList;
  FavPath: array[0..MAX_PATH] of Char;
  Count: Cardinal;
  s: String;
resourcestring
  strEndMessage1 = 'Es wurde(n) %d Link(s) aus den Favoriten gelöscht';
begin
  if LastPage then
  begin
    sl := TStringList.Create;
    try
      Count := 0;
      DeadLinks(sl);
      // User selected links in the listview
      if sl.Count > 0 then
      begin
        if ... then
        begin
        // Bookmark-File
        else
        begin
          Count := RewriteBookmarkFile(sl, edtFilename.Text);
        end;
      end;
    finally
      FreeAndNil(sl);
    end;
  // some more code
end;
Aber ich sehe keinen Unterschied.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.117 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: Problem mit speichern einer Stringliste

  Alt 9. Mär 2004, 00:40
Moin Luckie,

hast Du auch sichergestellt, dass die Datei nicht schreibgeschützt ist?

Übrigens solltest Du Deine Schleifenzähler mal als integer und nicht als cardinal deklarieren, sonst bekommst Du unerfreuliche Ergebnisse, wenn mindestens einer der beiden TStringList.Count gleich 0 ist, da der Wert count-1 dann nicht als -1 interpretiert wird.

Wofür hast Du noch die Variable Count deklariert?
Dafür kannst Du doch direkt Result verwenden.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Problem mit speichern einer Stringliste

  Alt 9. Mär 2004, 00:45
Nein, sie ist leider nicht schreibgeschützt. Ich habe echt keinen Plan und bin am verzweifeln, weil ich den Unterschied einfach nicht sehe.

Count habe ich deklariert, weil Hagen mal erklärt hatte, dass man result ganz zum Schluss zuweisen sollte, damit der Compiler den Code dahingegen optomieren kann, dass die CPU das Regsiter für result irgendwie nutzen kann oder so ähnlich. Wenn ich es finde poste ich es noch mal.

Habs:
Zitat:
Das Vorbelegen von Result ist überflüssig. Zu dem verhindert es die Codeoptimierung und macht die Registernutzung
unmöglich.
Delphi-Quellcode:
function BadResultUsage: Integer;
var
  I: Integer;
begin
  Result := 1;
  for I := 0 to 1024 do
    Result := Result + Result;
end;

function GoodUsage: Integer;
var
  I,J: Integer;
begin
  J := 1;
  for I := 0 to 1024 do
    J := J + J;
  Result := J;
end;
Dazu Hagen Reddmann:
"In komplexeren Sources wird nämlich in BadResultUsage das Resultat im Stack zwischen gespeichert. In
GoodUsage geben wir aber dem Optimierer in J die Berechnungsvariable vor, die der Optimierer innerhalb
der Loop in ein Register optimieren kann. Erst am Ende der Funktion wird das Resultat belegt, was meistens
durch den Optimierer einfach bedeutet das er das optimierte Register J ind Register EAX kopiert. In
BadResultUsage wäre dies aber im Stack gespeichert.
Wohlgemerkt obige Beispiele sind zu einfach, das heißt der Optimierer kann so wie sie sind beide optimal
umsetzen. Würde man aber viel mehr Code drinnen stehen haben tritt diese Regel in Kraft."
Und weiter:
"Der Optimierer versucht als erste wichtige Maßnahme die am häufigsten benutzten lokalen ordinalen Variablen
in Register zu optimieren. Sollten nicht genügend Register vorhanden sein um alle Lokale Variablen plus
der ordinalen Resultat Variablen in Registern zu speichern, so gerät der Optimierer und Druck, bzw. unter
Zugzwang. Als erstes wird er das Resultat als temporäre lokale Variable anlegen. Beim Exit aus der Funktion
wird dann dieser Inhalt in Register EAX kopiert. Ausnahme sind Fließkomma oder komplexe Datentypen.
Angenommen die Funktion nutzt nur sehr wenige lokale Variablen, es stehen also genügend freie Register
zur Verfügung. Wird nun dennoch Result sofort in der Funktion benutzt, statt eben erst ganz ganz zum
Schluss so wird der Optimierer ein Register benutzt das NICHT EAX ist. Erst am Schluss wird er das benutzte
Register, meistens ESI,EDI,EBX in das EAX Register kopieren. Dies bedeutet das wenn man das Resultat in
eine selbst definierte lokale Variable berechnet und erst ganz zum Schluss Result := LokaleVariable setzt der
Optimierer nun Freiheiten gewinnt. Er kann also selbständig entscheiden wie und wo er diese Lokale Variable
in welches Register optimiert. So oder so wird er am Exit der Funktion ein MOV EAX,reg durchführen.
Hintergrund bei dieser Logik ist der Fakt das nachdem Resultat am Anfang gesetzt wurde nun Aufrufe zu Unterprozeduren
erfolgen können. Er darf also NICHT EAX sofort als Resultat Register benutzen, da ja durch
den Unteraufruf EAX,EDX,ECX jederzeit zerstört werden können. Des weiteren ist die Standardaufrufkonvention
ja register, also EAX,EDX,ECX könnten bei Unterfunktionen als Parameter dienen. Nun, statt wie in
C/C++ aufwendige Analysen durchzuführen haben die Borlandianer anders gedacht. Sie benutzen die Regel
das EAX, EDX, ECX jederzeit zerstörbar sind und ESI, EDI, EBX immer innerhalb von Unterfunktionen durch
diese gesichert werden müssen. Somit können die Register ESI, EDI, EBX ohne weitere Source-Analyse als
Register-Lokale-Variablen benutzt werden. Statt also wie in C/C++ auf alle Eventualitäten durch komplette
Live-Analyse des gesamten Source zu optimieren, wie beim Borland Compiler von vornherein mit einem
Regelwerk gearbeitet. Der Optimierer optimiert so als wäre es im Scheiß egal welche Unterfunktionen noch
im Source stehen.
Nun, wird Result schon am Anfang der Prozedur gesetzt so muss der Optimierer diesen Wert als unsichtbare
temporäre lokale Variable auf dem Stack verwalten. "
Aber das soll hier jetzt bitte nicht das Thema sein.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.117 Beiträge
 
Delphi 11 Alexandria
 
#5

Re: Problem mit speichern einer Stringliste

  Alt 9. Mär 2004, 00:53
Moin Luckie,

also wenn die Datei nicht angelegt werden kann, könntest Du Dir vielleicht noch mal mit einem GetLastError weiterhelfen, um Näheres zu erfahren.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

Re: Problem mit speichern einer Stringliste

  Alt 9. Mär 2004, 00:57
Zitat:
---------------------------
Bookmark-Checker
---------------------------
Systemfehler. Code: 183.

Eine Datei kann nicht erstellt werden, wenn sie bereits vorhanden ist.
---------------------------
OK
---------------------------
Das verstehe ich nicht. Sonst hatte ich nie Probleme eine Datei in eine Stringliste zu laden, sie zu ändern und wieder unter dem gleichen Namen abzusoeichern.

Mache ich das:
Delphi-Quellcode:
    slBookmarkFile.LoadFromFile(Filename);
    DeleteFile(Filename);
Wird mir gesagt, dass das System nicht auf die Datei zugreifen kann, da sie von einem anderen Prozess benutzt wird.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#7

Re: Problem mit speichern einer Stringliste

  Alt 9. Mär 2004, 02:26
Kann es sein, dass FreeAndNil eine Datei einer StringListe nicht explizit schließt?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Problem mit speichern einer Stringliste

  Alt 9. Mär 2004, 03:43
Vergesst es. Ich habe die Datei an einer anderen Stelle nicht geschlossen. Das hat mich jetzt dreieinhalb Stunden gekostet.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz