![]() |
Fehler beim überschreiben von Datei
Wenn ich meine Datei die vorher mit hFile geschlossen wurde
überschreiben will bekomme ich einen EInOut Error
Delphi-Quellcode:
Der Fehler tiritt in der Zeile Rewrite(f); auf.
myFile := SKAERO_SaveFileDialog(MainHandle, 'MidiTracker files (*.mtf*)|*.mtf*', 'mtf', 'MidiTrackerFile');
AssignFile(f, myFile); Rewrite(f); Was mache ich falsch? Geschlossen wird es korrekt.
Delphi-Quellcode:
procedure FClose(var hFile: Cardinal);
begin if hFile <> 0 then CloseHandle(hFile); hFile := 0; end; gruss |
AW: Fehler beim überschreiben von Datei
Was genau für ein Fehler? Da gibts doch immer eine Nummer, oder? :)
|
AW: Fehler beim überschreiben von Datei
Zitat:
Meinst das ? ;) Ist aber geschlossen. EDIT: Fülle den Buffer
Delphi-Quellcode:
FBuffin(MidiTrackerFile);
Delphi-Quellcode:
Dann öffne ich die Datei und setze die Zugriffsrechte
procedure FBuffin(FileName: string);
var sBuffer: string; begin if not FExist(FileName) then Exit; nErrCode := FOpen(FileName, 0, 2, myFile); if nErrCode <> 0 then exit; nReading := 0; Assignfile(ParseFile, FileName); reset(ParseFile); while not eof(ParseFile) do begin ReadLN(ParseFile, sBuffer); FSeekTo(nReading, sBuffer); inc(nReading); end; end;
Delphi-Quellcode:
FOpen(FileName, 0, 2, myFile);
Nur Lesen 0= AccessIs := GENERIC_READ; Schreibzugriff verweigern. 2= ShareIs := FILE_SHARE_READ Nach dem einlesen der datei wird alles wieder geschlossen und auf nil gesetzt
Delphi-Quellcode:
Theoretisch dürfte jetzt kein zugriff auf die Datei mehr vorhanden sein.
// MidiTrackerFile schließen
FClose(myFile); FPBuffer := nil; FToPBuffer := nil; Result := True; Aber trotzdem kann ich sie nicht überschreiben. Die Zugriffsrechte dürften dann keinen Einfluss mehr auf die Datei haben nach dem schließen. gruss |
AW: Fehler beim überschreiben von Datei
Zitat:
Warum nicht
Delphi-Quellcode:
?
CloseFile(f);
|
AW: Fehler beim überschreiben von Datei
Zitat:
gruss |
AW: Fehler beim überschreiben von Datei
Delphi-Quellcode:
Hallo Emil,
if not FExist(FileName) then Exit;
nErrCode := FOpen(FileName, 0, 2, myFile); Du öffnest die Datei immer mit FOpen schliesst sie aber nie mit z.B. mit FClose. Reset öffnet die (Text)Datei zum Lesen - das scheint ja noch in Ordnung zu sein. Da die Datei mit 0= AccessIs := GENERIC_READ; Schreibzugriff verweigern. 2= ShareIs := FILE_SHARE_READ geöffnet wurde. Rewrite öffnet die Datei zum Schreiben - da kracht es weil die Datei nur zum Lesen geöffnet wurde. Grüße Klaus |
AW: Fehler beim überschreiben von Datei
Zitat:
Delphi-Quellcode:
Ist das ein Vielleicht FClose?
// MidiTrackerFile schließen
FClose(myFile); FPBuffer := nil; FToPBuffer := nil; Result := True; Zitat:
Siehe FClose.... Die zugriffsrechte haben dann keine Bedeutung mehr. Es sei denn das schließen des Handle allein genügt nicht! Und die Datei ist mehr oder weniger immer noch offen. Oder aber die zugriffsrechte werden in die Datei gespeichert! Dann wäre es verständlich wenn sie sich nicht überschreiben läßt. grrr.... gruss |
AW: Fehler beim überschreiben von Datei
wäre es nicht mal sinnvoll, einen größeren Teil des Quellcodes auszupacken? - Zumindest mit dem Teil hier habe ich so meine Probleme:
Zitat:
Bernhard |
AW: Fehler beim überschreiben von Datei
Zitat:
Globale Variablen habe ich rausgeschmissen und deklariere sie nun in meiner procedure direkt. Ich glaube den Mist habe ich vor langer zeit mal selbst verzapft. Ich denke weil ich zu der zeit (und immer noch nicht weis) wie ich hFile durch eine EOF schleife laufen lassen kann. Das ich die Datei dadurch 2 mal öffne ist mir nicht wirklich aufgefallen. EDIT: Sehe gerade kann hFile gar nicht mit EOF öffnen da EOF zu Pascal und hFile zur Win32 Api gehört. grrr.. muss dann wieder alles umschreiben. Ok geht jetzt.. Habe meine procedure umgeschrieben.
Delphi-Quellcode:
Die Datei dann nochmals über hFile zu öffnen macht dann nicht wirklich sinn.
procedure FBuffin(FileName: string);
var sBuffer: string; f : TextFile; begin if not FExist(FileName) then Exit; Assignfile(f, FileName); reset(f); while not eof(f) do begin ReadLN(f, sBuffer); FSeekTo(nReading, sBuffer); inc(nReading); end; CloseFile(f); end; gruss |
AW: Fehler beim überschreiben von Datei
Hallo Emil,
ich würde die FBuffin Procedure so umbauen, dass die Datei darin geöffnet und auch geschlossen wird.
Delphi-Quellcode:
So weit ich gesehen habe, wird die Variable hFile nicht
procedure FBuffin(FileName: string; {var hFile: THandle});
var sBuffer: string; f : TextFile; hFile : THandle; begin if not FExist(FileName) then Exit; nErrCode := FOpen(FileName, 2, 4, hFile); // Was willst Du damit bewecken? // Nur einen ErrorCode bekommen? if nErrCode <> 0 then exit; nReading := 0; Assignfile(f, FileName); {$I -} reset(f); {$I +} if IOResult = 0 then begin while not eof(f) do begin ReadLN(f, sBuffer); FSeekTo(nReading, sBuffer); inc(nReading); end; closeFile(f); end; fClose(hFile); end; in der Routine ParsetoMidiTracker verwendet (ausser für fClose). Grüße Klaus |
AW: Fehler beim überschreiben von Datei
Delphi-Quellcode:
FOpen(FileName, 2, 4, hFile);
Nein ich wollte die datei mit Zugriffsrechten öffnen. Das war der einzige Sinn und zweck.. Scheinbar ist mir da ein Denkfehler unterlaufen. Habe es jetzt so gelößt..
Delphi-Quellcode:
Danke für eure Hilfe
procedure FBuffin(FileName: string);
var sBuffer: string; f : TextFile; begin if not FExist(FileName) then Exit; Assignfile(f, FileName); reset(f); while not eof(f) do begin ReadLN(f, sBuffer); FSeekTo(nReading, sBuffer); inc(nReading); end; CloseFile(f); end; gruss |
AW: Fehler beim überschreiben von Datei
Dieses Snippet ist so nicht sicher...
Was ist, wenn aus welchen Gründen auch immer in der Schleife ein Fehler auftritt? In diesem Fall wird das Filehandle nicht geschlossen, dh. CloseFile(f); wird nicht unbedingt aufgerufen. Im weiteren Programmfluss könnte das zu Bugs führen! Daher packe das bitte in ein Try-Finally Konstrukt! |
AW: Fehler beim überschreiben von Datei
Zitat:
Meinst so? :)
Delphi-Quellcode:
procedure FBuffin(FileName: string);
var sBuffer: string; f : TextFile; begin if not FExist(FileName) then Exit; try Assignfile(f, FileName); reset(f); while not eof(f) do begin ReadLN(f, sBuffer); FSeekTo(nReading, sBuffer); inc(nReading); end; finally CloseFile(f); end; end; |
AW: Fehler beim überschreiben von Datei
ich würde da noch eine Fehlerbehandlung einbauen. Sonst wunderst du dich irgendwann warum nichts passiert und suchst dich wieder dumm und dämlich.
|
AW: Fehler beim überschreiben von Datei
Zitat:
Ideal wäre auch mit SchreibLeserechtzugriffen. Weil meine Skin.ini aus dem Programm keinesfalls mit Schreibrechten aufgerufen werden sollte. Deshalb habe ich auch den kram mit hFile überhaupt eingebaut. Aber nicht darauf geachtet das die Datei dadurch mehrfach geöffnet wird. So siehts jetzt aus.. Vielleicht kann es ja jemand brauchen muss halt die Routine für MediaTrackerfile umbauen.
Delphi-Quellcode:
unit uParseTrackerFile;
interface uses Classes, Windows, uGlobal, SKAeroAPI; type PParseFile = ^TParseFile; TParseFile = record Nr :Integer; Str : string; Ptr : PParseFile; Max : Integer; end; function FExist(FileSpec : string): Boolean; procedure FSeekTo(nReading: Integer; sBuffer: string); function ParsetoMidiTracker(MidiTrackerFile: string; ExePath: string; List: TStringList): Boolean; procedure FBuffin(FileName: string); implementation uses uMidiTracker; var LineStart : PParseFile; FPBuffer : PParseFile; FToPBuffer : PParseFile; nReading : Integer; function ParsetoMidiTracker(MidiTrackerFile: string; ExePath: string; List: TStringList): Boolean; var sParse : String; IntB: Integer; IntA: Integer; begin // Buffer Liste füllen FBuffin(MidiTrackerFile); if not assigned(FPBuffer) then begin result := False; exit; end; List.Delimiter := ','; FPBuffer := LineStart; while (FPBuffer.Nr <= LineStart.Max) do begin FPBuffer := FPBuffer^.Ptr; sParse := LeftTrim(FPBuffer.Str); if Length(sParse) <> 0 then begin List.DelimitedText := sParse; // Lade die Noten for IntA := 0 to 7 do begin for IntB := 0 to List.Count - 1 do Grid[IntA, IntB] := StrToInt(List.Strings[IntB]); inc(FPBuffer.Nr); FPBuffer := FPBuffer^.Ptr; sParse := LeftTrim(FPBuffer.Str); List.DelimitedText := sParse; for IntB := 0 to List.Count - 1 do InstGrid[IntA, IntB] := StrToInt(List.Strings[IntB]); inc(FPBuffer.Nr); FPBuffer := FPBuffer^.Ptr; sParse := LeftTrim(FPBuffer.Str); List.DelimitedText := sParse; end; // Lade das Tempo if (FPBuffer.Nr = 16) then begin for IntB := 0 to List.Count - 1 do MidiTracker.Tempo := StrToInt(List.Strings[IntB]); SKAERO_SetTrackValue(SKAERO_GetMainItem(MainHandle, ID_TRACK_TEMPO), MidiTracker.Tempo); TempoWait := 1000 div round((MidiTracker.Tempo / 15)); end; end; if not (FPBuffer.Nr >= LineStart.Max) then begin inc(FPBuffer.Nr); FPBuffer := FPBuffer^.Ptr; sParse := LeftTrim(FPBuffer.Str); List.DelimitedText := sParse; end; if (FPBuffer.Nr > 16) then begin for IntA := 0 to 7 do begin MidiTracker.CurrentInst[IntA] := StrToInt(List.Strings[IntA]); end; inc(FPBuffer.Nr); end else begin for IntA := 0 to 7 do MidiTracker.CurrentInst[IntA] := InstGrid[IntA, 0]; inc(FPBuffer.Nr); end; end; // Resourcen Freigeben FPBuffer := nil; FToPBuffer := nil; Result := True; end; procedure FBuffin(FileName: string); var sBuffer: string; f : TextFile; begin if not FExist(FileName) then Exit; try Assignfile(f, FileName); reset(f); while not eof(f) do begin ReadLN(f, sBuffer); FSeekTo(nReading, sBuffer); inc(nReading); end; finally nReading := 0; CloseFile(f); end; end; function FExist(FileSpec : string): Boolean; var hFile: Cardinal; lpFindFileData: TWin32FindData; begin Result := False; hFile := FindFirstFile(PAnsiChar(FileSpec), lpFindFileData); if hFile <> INVALID_HANDLE_VALUE then begin Windows.FindClose(hFile); Result := True; end; end; procedure FSeekTo(nReading: Integer; sBuffer: string); begin New(FPBuffer); if nReading = 0 then Begin New(FToPBuffer); LineStart := FToPBuffer; end; FPBuffer^.Nr := nReading; FPBuffer^.Str := sBuffer; LineStart^.Max := nReading; FToPBuffer^.Ptr := FPBuffer; FToPBuffer := FPBuffer; end; end. gruss |
AW: Fehler beim überschreiben von Datei
Ganz schlimmer Sourcecode. :duck:
Globale Variablen, Funktion die nicht das tun was man erwartet, wirre verkettete Listen, hart codierte Zahlen anstelle von Konstanten, Speicherlecks, usw. |
AW: Fehler beim überschreiben von Datei
Zitat:
|
AW: Fehler beim überschreiben von Datei
Zitat:
Delphi-Quellcode:
function ReadTextFile(Filename: AnsiString; AccessMode: Integer): AnsiString;
var F: TextFile; Line: AnsiString; FileContent: AnsiString; begin FileMode := AccessMode; AssignFile(F, Filename); try try Reset(F); while not EOF(F) do begin Readln(F, Line); FileContent := FileContent + Line + #13#10; end; except raise Exception.Create(SysErrorMessage(GetLastError)); end; finally CloseFile(F); end; Result := FileContent; end; procedure TForm15.Button1Click(Sender: TObject); const FILENAME = 'D:\Computer\exclude.lst'; var s: AnsiString; begin try s := ReadTextFile(FILENAME, fmOpenRead); ShowMessage(s); except on E: Exception do ShowMessage(E.Message); end; end; |
AW: Fehler beim überschreiben von Datei
Wozu den AccessMode angeben, wenn man eh nur lesen möchte? Und den Filename-Parameter könnte man auch als const deklarieren.
Just my 2 cents. |
AW: Fehler beim überschreiben von Datei
Weil Standard ist Lesen und Schreiben. Und ich habe eben gedacht, wenn man sie mal anders öffnen möchte, dann kann man das so bequem mit angeben. Und mit dem const hast du recht, das vergesse ich immer.
|
AW: Fehler beim überschreiben von Datei
Dann würde ich persönlich das aber so deklarieren:
Delphi-Quellcode:
function ReadTextFile(const Filename: AnsiString; AccessMode: Integer = fmOpenRead): AnsiString;
|
AW: Fehler beim überschreiben von Datei
OK, das sind jetzt Kleinigkeiten. Es ging ja um die Fehlerbehandlung.
|
AW: Fehler beim überschreiben von Datei
Sicherlich, aber wenn wenn man Code verbessern kann, spricht doch nichts dagegen. Das finde ich zumindest besser, als wenn auf die SuFu verwiesen wird und diese nur halbgare Lösungen zu Tage befördert (ich meine damit jetzt nicht diesen konkreten Fall).
|
AW: Fehler beim überschreiben von Datei
Zitat:
Zitat:
Zitat:
Zitat:
Wer schreibt mir vor in welchen Stil ich schreiben muss? Für mich zählt das ergebnis nicht ob ich eine für mich nichtssagende Konstante verwende oder hartcode. Solange wie der Compiler damit zurecht kommt. Sieht man das nachher in der Compilierten EXE? Kennst den Unterschied zwischen Dim X% und Dim X As Integer ? Siehste ... welche Schreibweise ist dir genehm wenn beides das gleiche Ergebnis liefert. gruss |
AW: Fehler beim überschreiben von Datei
Zitat:
Danke euche gruss |
AW: Fehler beim überschreiben von Datei
@Luckie:
Diese alten Pascal-Routinen nutzen IOResult und nicht GetLastError :zwinker: |
AW: Fehler beim überschreiben von Datei
Zitat:
Bei IOResult müssen die Schalterbefehle $I auf $I+ gesetzt werden. Ja, ja was für eine Ironie gruss |
AW: Fehler beim überschreiben von Datei
Könnte mir mal jemanderklären was es mit
Delphi-Quellcode:
auf sich hat?
FSeekto
Bei der Kombination
Delphi-Quellcode:
und
Seek
Delphi-Quellcode:
kringeln sich mir meist die Fingernägel.
Readln
Gruß K-H |
AW: Fehler beim überschreiben von Datei
Zitat:
Seek kommt von!
Zitat:
gruss |
AW: Fehler beim überschreiben von Datei
Meinst du nicht $I- ?
ich dachte $I+ schaltet die delphiseitige Prüfung an, womit Delphi dann exceptions wirft, wenn es nicht geht. Aber für Luckies Beispiel ist $I+ richtig, da er dort die delphiinterne Excepetions nutzt und in Try-Except IOResult auswerten würde. Bei $I- wird keine Exception geworfen und man muß im "normalen" Programmablauf auf IOResult prüfen, ob die vorherrigen Operationen erfolgreich waren. ja ja, das waren schon komische Fehlerbehandlungen damals. Wobei Seek und ReadLn garnicht zusammen funktionieren sollte. :shock: ReadLn ist nur für Textdateien und Seek sollte bei Textdateien nicht funktionieren und einen Fehler auslösen. (Da sich Borland es gespart hat den internen Textpuffer bei Seek zu behandeln und lieber einen Fehler auslöste) Also irgendwie ist mir diese ganze UIrgendwasParse-Unit etwas suspekt. |
AW: Fehler beim überschreiben von Datei
Zitat:
Zitat:
Ich fülle damit meine Variablen um nachher den start und endpunkt eines Textes über eine Abfrage besser identifizieren zu können.
Delphi-Quellcode:
procedure FSeekTo(nReading: Integer; sBuffer: string);
begin New(FPBuffer); if nReading = 0 then Begin New(FToPBuffer); LineStart := FToPBuffer; end; FPBuffer^.Nr := nReading; FPBuffer^.Str := sBuffer; LineStart^.Max := nReading; FToPBuffer^.Ptr := FPBuffer; FToPBuffer := FPBuffer; end;
Delphi-Quellcode:
usw..
FPBuffer := LineStart;
while (FPBuffer.Nr <= LineStart.Max) do begin Aber wie schon gesagt. Jeder so wie er am besten zurecht kommt. EDIT: So schlecht wie er hier hingestellt wird ist mein Code gar nicht ;) Einfacher wäre natürlich Copy/Paste hier aus dem Forum. gruss |
AW: Fehler beim überschreiben von Datei
Die Procedure FSeekTo müsste eigentlich AppendToLinkedList heissen; denn das ist genau das was passiert: der übergebene Puffer (in Form eines String) wird an die verkettete Liste angehängt. Mit "Seek" oder "FileSeek" hat die Prozedur nix zu tun.
Namensgebung ist beim Programieren einfach sehr wichtig; das darf man nicht auf die leichte Schulter nehmen. |
AW: Fehler beim überschreiben von Datei
Zitat:
Daher auch die Namensgebung PS: Zitat:
gruss |
AW: Fehler beim überschreiben von Datei
Um dich etwas zu stützen - was zählt, ist, dass letzendlich alles klappt.
Genau das ist aber das Ziel und ans Ziel zu gelangen sollte nicht unnötig erschwert werden indem man sich selbst Stolpersteine in den Weg legt (indem man z.B. hardkodierte Zahlen anstatt Konstanten verwendet) Ausschlaggebend wird das ganze dann beim Debuggen oder wiederverwenden der Codesnippets! Letzendlich willst du, dass dein Code funktioniert. Das tut es im Moment aber was ist, wenn du nach einer 3-4 monatigen Pause wieder mal dran arbeiten und ein paar Bugs beheben willst. Dir wird dann $02 nichts sagen! Konstanten hingegen dürften verständlicher und dir somit beim Erreichen deines "Zieles" (funktionierender & wiederverwendbarer Code) behilflicher sein! Es gibt unendlich viele Gründe, warum man Dinge richtig anpacken sollte - damit will ich nicht implizieren, dass deine Methode in irgendiner Form falsch wäre/ist. Aber es gibt bessere Wege! Und warum nicht diese begehen? :stupid: Edit: Dies bezieht sich auf diesen Text Zitat:
|
AW: Fehler beim überschreiben von Datei
Zitat:
"AnhaengenAnVerketteListe", "Speichern" oder "Merken" wäre hier korrekte Begriffe!! Demzufolge ist dein Prozedurname einfach sehr sehr irreführend. "AppendToLinkedList" wäre eine wirklich passende Beschreibung für die Prozedur. |
AW: Fehler beim überschreiben von Datei
Zitat:
@EWeiss: Die Kritik an deinen Code war nicht persönlich gemeint nur eine Konstruktive Kritik. Nehmen wir das Beispiel mit den Konstanten. Wenn du diese hart codest und sie ändern sich mal, bin ich mir zu hundert Prozent sicher, dass du nicht alle Stellen findest, wo du sie benutzt hast. Benutzt du aber eine benannte Konstante, musst du sie nur an einer Stelle im Code ändern. |
AW: Fehler beim überschreiben von Datei
Zitat:
Werd es dann mal berichtigen. Zitat:
Grundsätzlich gebe ich euch ja recht. IOResult der erste Eintrag bei Google ;)
Delphi-Quellcode:
var F: file of Byte;
begin Assign(F, ParamStr(1)); {$I-} Reset(F); {$I+} if IOResult = 0 then Writeln('Dateigröße in Byte ', FileSize(F)) else Writeln('Datei nicht gefunden'); end. gruss |
AW: Fehler beim überschreiben von Datei
Zitat:
Sobald ein Fehler auftrat, werden alle nachfolgenden Pascal-Datei-Routinen übergangen und nicht mehr ausgeführt. Und ist {$i} aktiviert (+), dann lößt der erste Fehler eine Exception aus und die Codebearbeitung wird unterbrochen. Achtung: Das Auslesen von IOResult setzt den internen Fehlercode wieder auf 0. (danach werden also die Dateiroutinen wieder ausgeführt) [add] Jetzt weiß ich auch endlich wieder, wieso ich mal auf die saublöde Idee kam, GetLastError würde seinen Fehlercode zurücksetzen. :wall: |
AW: Fehler beim überschreiben von Datei
Zitat:
|
AW: Fehler beim überschreiben von Datei
Zitat:
Nicht meins um die alten Schalter von Turbo Pascal zu dokumentieren. Wie sie damals angewendet wurde. gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:19 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