AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Unrealistischster Fehler aller Zeiten.
Thema durchsuchen
Ansicht
Themen-Optionen

Unrealistischster Fehler aller Zeiten.

Ein Thema von Sascha L · begonnen am 7. Jan 2005 · letzter Beitrag vom 8. Jan 2005
Antwort Antwort
Sascha L

Registriert seit: 4. Jun 2004
Ort: Hamm
390 Beiträge
 
Delphi 2006 Professional
 
#1

Unrealistischster Fehler aller Zeiten.

  Alt 7. Jan 2005, 13:23
Hallo,

ich habe folgenden Code (er ist erstmal nur zum Testen, daher ist er noch nicht mit try-Anweisungen, etc. optimiert worden):

Delphi-Quellcode:
procedure TForm1.MailsAbrufen;
var
//Integers
intIndex,i:integer;
begin
  try
  idPOP31.Connect;
  except
  MessageDlg('Es konnte keine Verbindung zum Postfach hergestellt werden. Bitte überprüfen Sie alle Einstellungen.',mtInformation,[mbOk],0);
  end;
  MailCount := idPOP31.CheckMessages;
  idPOP31.Retrieve(1,idMessage1);
  
  anhang_list := TStringList.Create;
  anhang_id_list := TStringList.Create;
  anhang_list_stream := TMemoryStream.Create;
  anhang_id_list_stream := TMemoryStream.Create;
  
  IBTable2.Last;
  ID2 := IBTable2.RecordCount;
  // Inhalt der Mail überprüfen
    if IdMessage1.MessageParts.Count <> 0 then begin
      for intIndex := 0 to (IdMessage1.MessageParts.Count-1) do begin
        if idMEssage1.MessageParts.Items[intIndex] is TIdText then begin
        mailBody := TidText(IdMessage1.MessageParts.Items[intIndex]).Body.Text;
        end
        else if idMEssage1.MessageParts.Items[intIndex] is TIdAttachmentFile then begin
        attFileName := (idMEssage1.MessageParts.Items[intIndex] as tIdAttachmentFile).Filename;
        TidAttachmentFile(idMessage1.MessageParts.Items[intIndex]).SaveToFile(path+'\tmp\'+attFileName);
        ID2 := ID2+1;
        anhang_id_list.Add(IntToStr(ID2));
        anhang_list.Add(attFileName);
        end;
      end;
    end
    else if IdMessage1.MessageParts.Count = 0 then begin
    MailBody := idMessage1.Body.Text;
    end;
     if anhang_list.Text <> 'then begin
     anhang_list.SaveToStream(anhang_list_stream);
     anhang_id_list.SaveToStream(anhang_id_list_stream);
     end;
  id1 := IBTable1.RecordCount+1;
  mailHeader := idMessage1.Headers.Text;
  mailSubject := idMessage1.Subject;
  mailDate := idMessage1.Date;
  mailFromName := idMessage1.From.Name;
  mailFromMail := idMessage1.From.Address;
  // Mails in die Datenbank speichern
  Mails2DB;
  // Alles wieder freigeben
  FreeAndNil(anhang_list);
  FreeAndNil(anhang_id_list);
  FreeAndNil(anhang_list_stream);
  FreeAndNil(anhang_id_list_stream);
  // Verbindung zum Server trennen
  idPOP31.Disconnect;
end;
//------------------------------------------------------------------------------
procedure TForm1.Mails2DB;
var
i:integer;
begin
  try
  // 1. Tabelle
  IBTable1.Insert;
  IBTable1.FieldByName('Message').AsString := mailBody;
  IBTable1.FieldByName('MSGID').AsInteger := id1;
  IBTable1.FieldByName('Header').AsString := mailHeader;
  IBTable1.FieldByName('Subject').AsString := mailSubject;
  IBTable1.FieldByName('Date').AsString := FormatDateTime('ddd, dd.mm.yyyy hh:mm', mailDate);
  IBTable1.FieldByName('FromName').AsString := mailFromName;
  IBTable1.FieldByName('FromMail').AsString := mailFromMail;
    if anhang_list.Text <> 'then begin
    anhang_list_stream.Position := 0;
    anhang_id_list_stream.Position := 0;
    Pic2DB.StoreStreamInDB(TBlobField(IBTable1.FieldByName('Anhang')),anhang_list_stream);
    Pic2DB.StoreStreamInDB(TBlobField(IBTable1.FieldByName('AID')),anhang_id_list_stream);
    IBTable1.FieldByName('AttIcon').AsInteger := 1;
    end;
  IBTable1.Post;
  // 2. Tabelle
   if anhang_list.count <> 0 then begin
    for i:=0 to anhang_list.Count-1 do begin
    IBTAble2.Insert;
    Pic2DB.StoreFileInDB(TBlobField(IBTable2.FieldByName('FILE')),path+'\tmp\'+anhang_list.Strings[i]);
    IBTable2.FieldByName('ID').AsInteger := StrToInt(anhang_id_list.Strings[i]);
    IBTable2.Post;
    end;
    end;
  // Ende
    mailsaved := true;
  except
    mailsaved := false;
  end;
end;
Das merkwürdige ist folgendes:

anhang_id_list ist leer. Das kann aber nicht. Wenn ich "Mails2DB" weglasse und an der Stelle den Inhalt von anhang_id_list in ein Memo lade, dann stehen dort 2 Zahlen (bei meiner Testmail), alle anderen Variablen sind auch ausgefüllt und die Schleife beim Anhang durchläuft er auch, da die Dateien im TMP-Ordner angelegt werden. Wenn ich aber die Prozedur "Mails2DB" verwende, sind anhang_id_list und anhang_id_list_stream wieder leer.

Ich versteh es einfach nicht und ein debuggen hat auch nichts gebracht.

Viele Grüße
Sascha
Sascha
  Mit Zitat antworten Zitat
Sascha L

Registriert seit: 4. Jun 2004
Ort: Hamm
390 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Unrealistischster Fehler aller Zeiten.

  Alt 7. Jan 2005, 15:12
wenn die Werte von anhang_id_list und anhang_id_list_stream in 2 neue Variablen schreibe und diese dann in die DB schreiben lasse, geht es komischerweise.

Das ist doch völlig unlogisch!

Selbst bei der Prozedur "Mails2DB" hat er der Inhalt von anhang_id_list_stream, aber bei der if-Schleife ist der Stream leer. Wenn ich aber in der Prozedur vor der if-Schleife den Inhalt des Streams in einen anderen Stream schreibe, dann geht es und wenn ich dann den neuen Stream angebe, schreibt er auch etwas in die DB.

Ist das ein Bug des Compilers??
Sascha
  Mit Zitat antworten Zitat
Benutzerbild von S - tefano
S - tefano

Registriert seit: 16. Dez 2002
Ort: Dülmen
477 Beiträge
 
Delphi 2009 Professional
 
#3

Re: Unrealistischster Fehler aller Zeiten.

  Alt 7. Jan 2005, 15:31
Das kann schlichtweg daran liegen, wie die Indys entwickelt sind.
Wenn ich in meinem FTPClient mit idFTP mir ein Verzeichnislisting geben lasse, geht das nur ein Mal und danach ist es wieder leer. Muss ich also auch auslagern...
"Damals" bei der ioresult-Variable war das auch so. Einmal auslesen, danach wieder auf 0.
Also würd ich sagen: It's not a bug, it's a feature
"Sir, we are surrounded!" - "Excellent, we can attack in every direction!"
  Mit Zitat antworten Zitat
Sascha L

Registriert seit: 4. Jun 2004
Ort: Hamm
390 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Unrealistischster Fehler aller Zeiten.

  Alt 7. Jan 2005, 16:22
nein, TMemoryStream ist nicht von Indy und hat daher nichts damit zu tun. Wenn eine Variable vom Typ Tmemorystream einen Wert hat, dann hat sie ihn.

Außerdem, wie eben erwähnt, ist der Inhalt ja bis zu if-Schleife vorhanden. Erst dann ist er wieder weg.
Sascha
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#5

Re: Unrealistischster Fehler aller Zeiten.

  Alt 7. Jan 2005, 16:38
Irgendwo ist das ganze fürn Ar***.
Hier mal der erste teil deines Quelltextes.
Delphi-Quellcode:
procedure TForm1.MailsAbrufen;
var
//Integers
intIndex,i:integer;
begin
  try
  idPOP31.Connect;
  except
  MessageDlg('Es konnte keine Verbindung zum Postfach hergestellt werden. Bitte überprüfen Sie alle Einstellungen.',mtInformation,[mbOk],0);
  end;
  MailCount := idPOP31.CheckMessages;
  idPOP31.Retrieve(1,idMessage1);
[...]
Wenn also das Connect fehl schlägt kommt eine Meldung und anschließend wird trotzdem versucht die nachrichten abzurufen Wie soll das gehen? Wenn keine Verbindung hergestellt werden kann so können auch keine Nachrichten abgerufen werden.

[OT]
Laut Delphistandard heißt es auch nicht
Delphi-Quellcode:
for [...] do begin
  //Anweisungen
end;

if [...] then begin
  //Anweisungen
end;
sondern
Delphi-Quellcode:
for [...] do
begin
  //Anweisungen
end;

if [...] then
begin
  //Anweisungen
end;
So sieht man wenigstens auf anhieb wo das end dazu gehört (denn zu einem "for" oder "if" gehört nicht zwingend ein "end" und es ist nicht grad schön zu lesen wenn ich immer erst das ende der zeile suchen muss (eventuell sogar scrollen) um zu wissen ob ein "begin" zur anweisung gehört oder ob es eine einzilge Anweisung ist
[/OT]

wo liegt eigentlich der Sinn von
Delphi-Quellcode:
if IdMessage1.MessageParts.Count <> 0 then //<==
begin
  for intIndex := 0 to (IdMessage1.MessageParts.Count-1) do
  begin
    if idMEssage1.MessageParts.Items[intIndex] is TIdText then
    begin //bei Einzelanweisungen ist "begin end" überflüssig
      mailBody := TidText(IdMessage1.MessageParts.Items[intIndex]).Body.Text;
    end
    else if idMEssage1.MessageParts.Items[intIndex] is TIdAttachmentFile then
    begin
      attFileName := (idMEssage1.MessageParts.Items[intIndex] as tIdAttachmentFile).Filename;
      TidAttachmentFile(idMessage1.MessageParts.Items[intIndex]).SaveToFile(path+'\tmp\'+attFileName);
      ID2 := ID2+1;
      anhang_id_list.Add(IntToStr(ID2));
      anhang_list.Add(attFileName);
    end;
  end;
end
else if IdMessage1.MessageParts.Count = 0 then //<==
begin //bei Einzelanweisungen ist "begin end" überflüssig
  MailBody := idMessage1.Body.Text;
end;
Wenn do oben auf ungleich 0 prüfst musst du unten kein "else if gleich 0" machen, da reicht auch ein einfaches else (sorry das ich den source bei dem beispiel mal bissl anders formatiert hab, aber sonst sieht man überhaupt ni durch was wozu gehört)
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Sascha L

Registriert seit: 4. Jun 2004
Ort: Hamm
390 Beiträge
 
Delphi 2006 Professional
 
#6

Re: Unrealistischster Fehler aller Zeiten.

  Alt 7. Jan 2005, 17:05
ich habe doch gesagt, dass ich das nur zum testen auf die schnelle gemacht habe und die feinoptimierung noch kommt.

für mich ist "if ... then begin" identisch mit

"if ... then
begin"

Diese Dinge haben nichts mit dem Fehler zu tun, ebenso die Sache mit "else"
Sascha
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#7

Re: Unrealistischster Fehler aller Zeiten.

  Alt 7. Jan 2005, 17:11
ist schon klar das dies nix mit dem Fehler zu tun hat, es ist eben nur aufwendig wenn man erst deinen source kopieren muss und ordentlich einrücken weil
Delphi-Quellcode:
        else if idMEssage1.MessageParts.Items[intIndex] is TIdAttachmentFile then begin
        attFileName := (idMEssage1.MessageParts.Items[intIndex] as tIdAttachmentFile).Filename;
        TidAttachmentFile(idMessage1.MessageParts.Items[intIndex]).SaveToFile(path+'\tmp\'+attFileName);
        ID2 := ID2+1;
        anhang_id_list.Add(IntToStr(ID2));
        anhang_list.Add(attFileName);
        end;
gar keine Einrückung hat (eigentlich wir das zwischen begin und end eingerückt).

Zum Fehler. Woher weißt du das in dem Stream nix drin steht? Durch den Debugger?
Wenn du vor
Pic2DB.StoreStreamInDB(TBlobField(IBTable1.FieldByName('AID')),anhang_id_list_stream); ein
anhang_id_list_stream.SaveToFile(YourFilename); einfügst ist die datei dann auch leer? Wenn nicht würde ich einfach drauf tippen das deine "Pic2DB" einen fehler hat oder der cast "TBlobFiled(IBTable1.FiledByName('AID'))" fehl schlägt.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Sascha L

Registriert seit: 4. Jun 2004
Ort: Hamm
390 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Unrealistischster Fehler aller Zeiten.

  Alt 8. Jan 2005, 11:25
Der Fehler: Listenindex überschreibt das Maximum von (0).

der Fehler passiert hier:

Delphi-Quellcode:
if anhang_list.count <> 0 then begin
    for i:=0 to anhang_list.Count-1 do begin
    IBTAble2.Insert;
    Pic2DB.StoreFileInDB(TBlobField(IBTable2.FieldByName('FILE')),path+'\tmp\'+anhang_list.Strings[i]);
    IBTable2.FieldByName('ID').AsInteger := StrToInt(anhang_id_list.Strings[i]);
    IBTable2.Post;
    end;
    end;
Vor der if-Schleife ist der Stream noch voll, weil ich Ihn testweise in ein Memo geladen habe. In der if-Schleife ist er leer. Ebenfalls mit einem Memo getestet.

An der Pic2DB-Komponente liegt es nicht, weil sie sonst einwandfrei funktioniert und das merkwürdige ist ja, dass ich nun vor der if-schleife einen 2. Stream erstelle und den Inhalt von anhang_id_list_stream dort hineinlade und diesen dann bei Pic2DB angebe. So klappt es merkwürdigerweise. Aber das ist doch unlogisch oder nicht? Ein Stream kann sich doch nicht, ohne Grund, innerhalb einer if-Schleife leeren.

Gruß
Sascha

EDIT:

Ich habe nun auch noch festellen dürfen (komischerweise klappte es die ganze Zeit), dass mein Programm hier abstürzt:

FreeAndNil(anhang_id_list_stream);

Erstellt wurde der Stream ja... d.h. er muss irgendwo vernichtet werden. Aber warum?? Ich habe nirgendswo stehen, dass er den Stream vernichten soll, außer an der einen Stelle, aber da wurde er komischerweise schon vorher vernichtet.
Sascha
  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 04:55 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