2012-08-23 8 views
5

Ich versuche, mit TFilestream auf eine Netzwerkfreigabe (lokal) zu schreiben. Alles funktioniert gut, sollte die Netzwerkverbindung nicht unterbrochen werden.Delphi Schreiben in eine Netzwerkfreigabe mit TFilestream sperrt die Datei, wenn das Netzwerk verloren geht

Wenn ich jedoch das Netzwerkkabel ziehen und dann erneut verbinden, scheitern nachfolgende Versuche, den Dateistream zu öffnen, aufgrund von Zugriffsbeschränkungen. Ich kann die Datei auch nicht im Explorer löschen! Es scheint, dass TFilestream die Datei sperrt und die einzige Möglichkeit, dies zu umgehen, ist ein Neustart.

In meiner Anwendung halte ich die Datei die ganze Zeit offen, während ich schreibe (es ist eine Protokolldatei, die einmal pro Sekunde geschrieben wird).

Mein Code, der unter fehlschlägt:

procedure TFileLogger.SetLogFilename(const Value: String); 
var line : String; 
Created : Boolean; 
begin 
    if not DirectoryExists(ExtractFilePath(Value)) then //create the dir if it doesnt exist 
    begin 
     try 
     ForceDirectories(ExtractFilePath(Value)); 
     except 
     ErrorMessage(Value); //dont have access to the dir so flag an error 
     Exit; 
     end; 
    end; 
    if Value <> FLogFilename then //Either create or open existing 
    begin 
     Created := False;   
     if Assigned(FStream) then 
     FreeandNil(FStream); 
     if not FileExists(Value) then //create the file and write header 
     begin 
      //now create a new file 
      try 
       FStream := TFileStream.Create(Value,fmCreate); 
       Created := True; 
      finally 
      FreeAndNil(FStream); 
      end; 
      if not Created then //an issue with creating the file 
      begin 
       ErrorMessage(Value); 
       Exit; 
      end; 
      FLogFilename := Value; 
      //now open file for writing 
      FStream := TFileStream.Create(FLogFilename,fmOpenWrite or fmShareDenyWrite); 
      try 
       line := FHeader + #13#10; 
       FStream.Seek(0,soFromEnd); 
       FStream.Write(Line[1], length(Line)); 
       FSuppress := False; 
      except 
       ErrorMessage(Value); 
      end; 
     end else begin //just open it 
      FLogFilename := Value; 
      //now open file for writing 
      FStream := TFileStream.Create(FLogFilename,fmOpenWrite or fmShareDenyWrite); //This line fails if the network is lost and then reconnected 
     end; 
    end; 
end; 

Wenn jemand einen Rat hat, würde es geschätzt.

+0

Ist das wirklich ein Problem mit TFileStream? Wenn ja, dann verwende einfach etwas anderes, wie CreateFile. –

Antwort

0

Ich mache etwas ähnliches, aber nicht TFileStream verwenden. Ich verwende Dateimethoden von SysUtils. Hier ist im Grunde, was ich tun, angepasst an Ihre Situation:

// variables used in pseudo-code below 
var 
    fHandle, bytesWriten: Integer; 
    Value: string; 
  • Öffnen Sie die Ausgabedatei mit fHandle := FileOpen('filename', fmOpenReadWrite or ...).
  • Überprüfen ist fHandle > -1, Schlaf und Schleife, wenn es nicht ist.
  • Schreiben Sie den Ausgang bytesWritten := FileWrite(fHandle, Value, Length(Value));.
  • Überprüfen Sie die bytesWritten, sie sollten = Length(Value).
  • Wenn die bytesWritten0 sind, wissen Sie, dass das Dateihandle verloren gegangen ist. Ich legte einen try ... finally Block um alle meine Code und führen if fHandle > -1 then try FileClose(fHandle); except end;, so dass es das System zwingt, die Datei behandeln, selbst wenn die Datei nicht mehr zugänglich ist.
  • Wenn die bytesWritten0 war, dann ruhen Sie für ein paar Sekunden und versuchen Sie es erneut.

Es scheint, als ob ich ein ähnliches Problem hatte, wie Sie beschreiben, bis ich den Code hinzugefügt:

if fHandle > -1 then 
    try 
    FileClose(fHandle); 
    except 
    end; 

I (langsam) Netzwerkfreigabe mit diesem Ansatz zu einer Remote-Gigabyte-Dateien kopiert, und das Netzwerk Die Freigabe wurde während der Kopie mehrmals verloren. Ich kann die Kopie fortsetzen, sobald die Netzwerkfreigabe wieder verfügbar ist. Sie sollten in der Lage sein, etwas Ähnliches mit Ihrer Protokolldatei zu machen ...

+4

Dies ist nicht die Antwort. Was ist, wenn das Netzwerk niemals zurückkommt? Jetzt ist das Programm in einer aktiven Schleife hängen. FWIW keine Notwendigkeit altmodische Datei-API zu verwenden, könnte dieser Code leicht mit einem TFileStream geschrieben werden. –

+0

Der Code, dem ich diesen Code entwarf, hat einen maximalen Wiederholungszähler, so dass er nicht in einer geschäftigen Schleife eingeschlossen wird; das ist einfach hinzuzufügen. Ich wusste nicht, ob TFileStream und die altmodische Datei-API die Dinge anders gehandhabt haben und ob das ein Teil des Problems sein könnte. Da ich weiß, dass es mit der Datei-API funktioniert, wollte ich, dass Simon weiß, wie diese Option funktioniert ... –

Verwandte Themen