Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi {$I-} und {$I+} (https://www.delphipraxis.net/5352-%7B%24i-%7D-und-%7B%24i-%7D.html)

Luckie 3. Jun 2003 10:51


{$I-} und {$I+}
 
So sieht jetzt meine Routine aus Zummzusammenfuegen der Dateien. Meine Frage ist jetzt: Habe ich die {$I-} und {$I+} richtig gesetzt? Und wie faengt man Fehler von BlockRead und BlockWrite ab?

Delphi-Quellcode:
{-----------------------------------------------------------------------------
  Procedure : thrJoinFiles - 2003-06-02 04:22:28
  modified : 2003-06-03
  Author   : Michael Puff
  Purpose  : Thread for joining the file parts
  Arguments : p : pointer
  Result   : Integer
-----------------------------------------------------------------------------}

function thrJoinFiles(p : pointer) : Integer;
var
  DestFile, SourceFile: File;
  i: Integer;
  buffer : array [0..255] of Char;
  s : String;
  MemBuffer : array[0..BLOCKSIZE] of Byte;
  BytesRead, TotalBytesWritten: Integer;
  y : Integer;
label
  TheEnd;
begin
  bRunningJoin := 1;
  result := 0;
  TotalBytesWritten := 0;
  SendDlgItemMessage(hApp, IDC_PROGBAR, PBM_SETPOS, 0, 0);
{$I-}
  AssignFile(DestFile, sFile);
  Rewrite(DestFile, 1);
  if IOResult <> 0 then
  begin
    RaiseLastError(hApp);
{$I+}
    goto TheEnd;
  end;
  for i := 0 to SendDlgItemMessage(hTabDlgs[1], IDC_LST_FILEPARTS, LB_GETCOUNT, 0, 0)-1 do
  begin
    SendDlgItemMessage(hTabDlgs[1], IDC_LST_FILEPARTS, LB_SETCURSEL, i, 0);
    { we need them in the correct order and the listbox ist sorted! }
    SendDlgItemMessage(hTabDlgs[1], IDC_LST_FILEPARTS, LB_GETTEXT, i,
      Integer(@buffer));
    s := Format('Teildatei: %d', [i+1]);
    SetDlgItemText(hApp, IDC_STC_STATUSWND, pointer(s));
    { build filename }
    s := sJoinFiles[0] + '\' + string(buffer);
{$I-}
    AssignFile(SourceFile, s);
    Reset(SourceFile, 1);
    if IOResult <> 0 then
    begin
      RaiseLastError(hApp);
{$I+}
      goto TheEnd;
    end;
    while not eof(SourceFile) do
    begin
      if bRunningJoin = 0 then
      begin
        CloseFile(DestFile);
        goto TheEnd;
      end;
      BlockRead(SourceFile, MemBuffer, sizeof(memBuffer), BytesRead);
      BlockWrite(DestFile, MemBuffer, BytesRead);
      TotalbytesWritten := TotalbytesWritten + BytesRead;
      y := Round((TotalBytesWritten / GetFileSize(Buffer)) * 100);
      SendDlgItemMessage(hApp, IDC_PROGBAR, PBM_SETPOS, y, 0);
    end;
    CloseFile(SourceFile);
    SendDlgItemMessage(hApp, IDC_PROGBAR, PBM_SETPOS, 0, 0);
    TotalBytesWritten := 0;
  end;
  TheEnd :
  CloseFile(DestFile);
  SetDlgItemText(hApp, IDC_STC_STATUSWND, nil);
  SendDlgItemMessage(hApp, IDC_PROGBAR, PBM_SETPOS, 0, 0);
  EnableWindow(GetDlgItem(hTabDlgs[1], IDC_BTN_OPENJOINFILES), TRUE);
  EnableWindow(GetDlgItem(hTabDlgs[1], IDC_BTN_DELFILE), TRUE);
  EnableWindow(GetDlgItem(hTabDlgs[1], IDC_BTN_SAVEAS), TRUE);
  EnableWindow(GetDlgItem(hTabDlgs[1], IDC_CHK_DELPARTS), TRUE);
  EnableWindow(GetDlgItem(hTabDlgs[1], IDC_BTN_JOIN), TRUE);
  EnableWindow(GetDlgItem(hTabDlgs[1], IDC_BTN_CANCELJOIN), FALSE);
end;
PS.:
Die Diskussion mit dem Label und den goto wollen wir hier bitte erst gar nicht anfangen. Ich halte es hier fuer recht sinnvoll.

Domo Sokrat 3. Jun 2003 10:59

Hi Lucky,

es reicht eigentlich aus, wenn Du die Dateioperation (z. B. Rewrite()) zwischen {$I-} und {$I+} stellst.

Sähe dann in etwa so aus:

Code:
 
  :
  SendDlgItemMessage(hApp, IDC_PROGBAR, PBM_SETPOS, 0, 0);
  AssignFile(DestFile, sFile);
  {$I-}
     Rewrite(DestFile, 1);
  {$I+}
  if IOResult <> 0 then
  :
Bei mir gab's nie Probleme mit dieser Methode.

Domo Sokrat 3. Jun 2003 11:01

Sorry für den Vertipper in Deinem Namen :oops: Asche auf mein Haupt! Das passiert, wenn man zu viele Dinge auf einmal macht...

Luckie 3. Jun 2003 11:06

Und wenn Rewrite bzw. Reset fehlschlaegt, dann kann BlockRead und BlockWrite ja nicht mehr funktionieren, das heisst also, die muesste ich nicht noch mal extra kapseln, wenn ich schon bei Reset bzw. Rewrite aussteige - denke ich mir jetzt mal so.

CalganX 3. Jun 2003 11:29

Also an sich ist das richtig.
Wenn du den Hinweis meines Vorredners befolgst, kommt es auf das gleiche heraus.

Aber nochwas: Wie kannst du es wagen Labels zu verwenden??? :kotz:

Chris

MathiasSimmack 3. Jun 2003 11:37

Weil er sonst den ganzen (Reset/Initialisierungs-)Kram am Ende min. 3x schreiben müsste. Für jede Abbruchmöglichkeit der Funktion nämlich. Und da ist ein Label tatsächlich mal nützlich, zumal nur in eine Richtung gesprungen wird.

@Luckie: Ich schreib´s immer so:
Delphi-Quellcode:
{$I-}
AssignFile(f,'bla.bla');
ReSet(f,1);

// mach was mit der geöffneten Datei

CloseFile(f);
{$I-}
Alte Angewohnheit von TP für DOS. :)

Luckie 3. Jun 2003 11:38

Was ist in diesem Fall gegen die Labels einzuwenden bitte sehr? Wie haettest du es denn geloest ohne die Uebersicht zu verlieren? Mit if's? Na dann aber viel Spass mit den verschachtelten if's ueber mehr als eine Bildschirmseite. Wenn ich mich nit verzaehlt habe waren das vier Ebenen deren Anfang und Ende sehr weit auseinander liegen.

Luckie 3. Jun 2003 11:43

Zitat:

Zitat von MathiasSimmack
Weil er sonst den ganzen (Reset/Initialisierungs-)Kram am Ende min. 3x schreiben müsste. Für jede Abbruchmöglichkeit der Funktion nämlich. Und da ist ein Label tatsächlich mal nützlich, zumal nur in eine Richtung gesprungen wird.

Genau deswegen. Jetzt ist alles am Ende und wenn was schiefgeht, springe ich einfach dahin - fertig ist die Laube.
Zitat:

@Luckie: Ich schreib´s immer so:
Delphi-Quellcode:
{$I-}
AssignFile(f,'bla.bla');
ReSet(f,1);

// mach was mit der geöffneten Datei

CloseFile(f);
{$I-}

Und wo faengst du dann IOResult ab?

Domo Sokrat 3. Jun 2003 11:43

Bissi spät, aber jetzt doch nochmal:
Du hast recht mit den anderen I/O-Zugriffen! Die Geschichte gilt übrigens (so wie ich's gelernt habe) für jeden I/O-Zugriff. Wenn Du also eventuelle Fehler in besagten Zeilen (BlockRead und BlockWrite) auch noch abfangen willst/musst, wäre es sinnvoll, diese Zeilen ebenfalls zwischen {I-} und {I+} einzufassen. Allerdings kann ich Dir jetzt aus der Lamenge nicht sagen, ob jeder Befehl für sich gekapselt werden muss oder ob beide zusammen gekapselt werden können. Müsstest Du mal ausprobieren.

Motzi 3. Jun 2003 11:45

Eíne andre Frage.. wieso verwendest du die alten DOS-like Funktionen wie AssignFile BlockRead/Write etc? Ich würde entweder FileStreams oder bei nonVCL direkt auf die WinAPIs zugreifen...!

Zu dem Label.. ;) Ich hätt eine Prozedur erstellt, die den Teil nach dem Label enthält. Mit einem Aufruf der Prozedur und einem darauffolgenenden Exit hätte man dasselbe Ergebnis.. BTW: du schließt DestFile zweimal ;)
Delphi-Quellcode:
      if bRunningJoin = 0 then
      begin
        CloseFile(DestFile); // <--
        goto TheEnd;
      end;
Delphi-Quellcode:
  TheEnd :
  CloseFile(DestFile); // <--
  SetDlgItemText(hApp, IDC_STC_STATUSWND, nil);


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:44 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz