![]() |
{$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:
PS.:
{-----------------------------------------------------------------------------
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; Die Diskussion mit dem Label und den goto wollen wir hier bitte erst gar nicht anfangen. Ich halte es hier fuer recht sinnvoll. |
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:
Bei mir gab's nie Probleme mit dieser Methode.: SendDlgItemMessage(hApp, IDC_PROGBAR, PBM_SETPOS, 0, 0); AssignFile(DestFile, sFile); {$I-} Rewrite(DestFile, 1); {$I+} if IOResult <> 0 then : |
Sorry für den Vertipper in Deinem Namen :oops: Asche auf mein Haupt! Das passiert, wenn man zu viele Dinge auf einmal macht...
|
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.
|
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 |
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:
Alte Angewohnheit von TP für DOS. :)
{$I-}
AssignFile(f,'bla.bla'); ReSet(f,1); // mach was mit der geöffneten Datei CloseFile(f); {$I-} |
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.
|
Zitat:
Zitat:
|
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. |
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. |
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