AGB  ·  Datenschutz  ·  Impressum  







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

Fehlertoleranz DELPHI, TEIL #2

Ein Thema von bernhard_LA · begonnen am 1. Dez 2012 · letzter Beitrag vom 1. Dez 2012
Antwort Antwort
Seite 1 von 2  1 2      
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.123 Beiträge
 
Delphi 11 Alexandria
 
#1

Fehlertoleranz DELPHI, TEIL #2

  Alt 1. Dez 2012, 08:26
wir haben in unserem Team folgende Funktion aus dem Internet gefunden, angepasst und in einer unit implementiert die dann in mehreren Anwendungen verwendet wird.



Delphi-Quellcode:

procedure LoadStringFromFile(Filename: string; var LoadString: string);
var
  fs: TFileStream;
begin
  fs := TFileStream.Create (Filename, fmOpenRead or fmShareDenyNone);
  try
    SetLength (LoadString, fs.Size);
    if fs.size>0 then
      fs.Read (LoadString[1], fs.Size);
  finally
    fs.Free;
  end;
end;

Beim Kopieren dieser Funktion aus dem Internet ist uns ein kleiner Fehler unterlaufen, wir haben beim Rückgabeparameter das var vergessen.

Delphi-Quellcode:

procedure LoadStringFromFile(Filename: string; LoadString: string);

bei zwei Anwendungen hat dieser Code fehlerfrei funktioniert, bei der dritten Anwendung haben wir beim Debuggen dann unseren Fehler entdeckt und behoben.
Die Frage ist nur " Warum hat dieser fehlerhafte Code trotzdem funktioniert ????"
  Mit Zitat antworten Zitat
Benutzerbild von Desmulator
Desmulator

Registriert seit: 3. Mai 2007
Ort: Bonn
169 Beiträge
 
#2

AW: Fehlertoleranz DELPHI, TEIL #2

  Alt 1. Dez 2012, 08:35
Im ersten Moment fällt mir nur ein, dass Strings ja auch lediglich nur pointer sind und die eigentlichen Zeichen, sowie die Länge schon per Referenz übergeben werden. Also werden auch Manipulationen an den selben String durchgeführt. Vielleicht ist beim dritten Programm mehr Compilermagic am Werk und der String wird zunächst kopiert?
Lars
There are 10 kinds of people in the world:
those who get binary, and those who don’t.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.015 Beiträge
 
Delphi 12 Athens
 
#3

AW: Fehlertoleranz DELPHI, TEIL #2

  Alt 1. Dez 2012, 08:36
Nur eine Vermutung: die automatische Referenzzählung bei Strings wirkt nur bei direkten Zuweisungen? Daher arbeitet das SetLength mit dem übergebenen StringPointer (das TStream.Read macht das sowieso).
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Fehlertoleranz DELPHI, TEIL #2

  Alt 1. Dez 2012, 08:40
Aus dem gleichen Grund, warum man bei einer reinen Übergabe von einem string das mit const machen sollte.

Es funktioniert, wenn der string Parameter vor der Übergabe an die Funktion mit genug Daten gefüllt war.

Ich hätte hier aber den Parameter eher als out und nicht als var deklariert.
Von der reinen Funktion macht es keinen Unterschied, somit ist aber dokumentiert, das der Wert in dem Parameter die Funktion nicht beeinflusst.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#5

AW: Fehlertoleranz DELPHI, TEIL #2

  Alt 1. Dez 2012, 08:44
Mal unabhängig von der Ursachenforschung; die korrekte Funktion sieht so aus:
Delphi-Quellcode:
function LoadStringFromFile(const Filename: string):AnsiString;
var
  fs: TFileStream;
begin
  fs := TFileStream.Create (Filename, fmOpenRead or fmShareDenyNone);
  try
    SetLength(Result, fs.Size);
    if fs.size>0 then
      fs.ReadBuffer(Result[1], Length(Result));
  finally
    fs.Free;
  end;
end;
Als Funktion lässt sich der Code im Gegensatz zur Prozedur aus dem 1. Beitrag flexibler einsetzen.

Geändert von sx2008 ( 1. Dez 2012 um 09:18 Uhr) Grund: Read() -> ReadBuffer() geändert
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.150 Beiträge
 
Delphi 12 Athens
 
#6

AW: Fehlertoleranz DELPHI, TEIL #2

  Alt 1. Dez 2012, 08:59
Auch wenn sx2008 unbewust die Lösung verbaut hat.

D2009 + String + Unicode?

Nachdem nun schon über 3 Jahre lang alle darüber schreiben, daß nun ein String nicht mehr ANSI, sopnder unicode ist, dürften das langsam mal bekannt werden, vorallem da die Sunchfunktion mit entsprechenden Beiträgen überfüllt sein dürfte.


Und die Frage nach dem Warum:
Wenn man Glück hat, dann gibt es nur eine Referenz und im Stream sind genau doppelt soviele Daten (Bytes), wie Daten im String (Bytes),
also genausoviele Bytes im Stream, wie Chars (je 2 Bytes) m String,
denn dann macht SetLength nämlich garnichts.
Und wenn dann beim Zugriff auf den String ebenfalls nichts mit der Referenzierung passiert, dann wird direkt in den externen String geschrieben.
(aber eigentlich sollte nur bei CONST eine passende Referenz reinkommen )
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 1. Dez 2012 um 09:07 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.150 Beiträge
 
Delphi 12 Athens
 
#7

AW: Fehlertoleranz DELPHI, TEIL #2

  Alt 1. Dez 2012, 09:06
[del]
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#8

AW: Fehlertoleranz DELPHI, TEIL #2

  Alt 1. Dez 2012, 09:14
Mal unabhängig von der Ursachenforschung; die korrekte Funktion sieht so aus:
Mal unabhängig von der Ursachenforschung; die ursprüngliche Funktion aus dem Internet hatte Boolean als Rückgabewert, und die sagte einem ob die Funktion erfolgreich war. Man kann auch String als Rückgabewert nehmen, muss dann aber selbst auf Erfolg prüfen.
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#9

AW: Fehlertoleranz DELPHI, TEIL #2

  Alt 1. Dez 2012, 09:24
die ursprüngliche Funktion aus dem Internet hatte Boolean als Rückgabewert, und die sagte einem ob die Funktion erfolgreich war
Das ist eine schlechte Technik (siehe Thread http://www.delphipraxis.net/171901-f...ml#post1193831).
Ich habe oben noch den Aufruf von Read() nach ReadBuffer() geändert.
Somit ist gewährleistet, dass die Funktion entweder mit dem String zurückkehrt oder eine Exception liefert.
Der einzige Schwachpunkt wären Dateien die grösser sind als der String an Daten aufnehmen kann (2/4GB-Limit).
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.150 Beiträge
 
Delphi 12 Athens
 
#10

AW: Fehlertoleranz DELPHI, TEIL #2

  Alt 1. Dez 2012, 09:32
Dann wirft SetLength eine schöne Exception und man hat ebenfalls ein passendes Ergebnis.

Nja, aber du meinst 1, bzw 1.5 GB (4 GB nicht, denn das ist nicht umsonst eine 3GB-Option), denn dre String braucht einen zusammenhängenden Speicherblock.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 12:44 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