2012-08-23 31 views
5

我試圖使用TFilestream寫入網絡共享(本地)。如果網絡連接不被中斷,它一切正常。使用TFilestream寫入網絡共享的Delphi在網絡丟失時鎖定文件

但是,如果我拔出網線並重新連接,則由於訪問限制,後續嘗試打開文件流失敗。我也無法刪除資源管理器中的文件! TFilestream似乎鎖定了文件,解決此問題的唯一方法是重新啓動。

在我的應用程序中,我一直保持文件打開,一直寫到它(它是每秒寫入一次的日誌文件)。

我的代碼失敗低於:

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; 

如果任何人有任何意見,我們將不勝感激。

+0

這是真的TFileStream問題?如果是這樣,那麼就使用其他的東西,比如CreateFile。 –

回答

0

我做了類似的事情,但不使用TFileStream。我使用SysUtils的文件方法。這基本上是我做的,適合您的情況:

// variables used in pseudo-code below 
var 
    fHandle, bytesWriten: Integer; 
    Value: string; 
  • 打開使用fHandle := FileOpen('filename', fmOpenReadWrite or ...)輸出文件。
  • 驗證是fHandle > -1,如果不是,則爲睡眠和循環。
  • 編寫輸出bytesWritten := FileWrite(fHandle, Value, Length(Value));
  • 檢查bytesWritten,他們應該= Length(Value)
  • 如果bytesWritten0,則知道文件句柄丟失。我在我的所有代碼周圍放了一個try ... finally塊,並執行if fHandle > -1 then try FileClose(fHandle); except end;,這樣即使文件不再可訪問,它也會強制系統釋放文件句柄。
  • 如果bytesWritten0,然後睡覺幾秒鐘,然後再試一次。

好像我也有類似的問題,因爲你描述的,直到我添加的代碼:

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

我一直在使用這種方法複製技嘉文件到遠程(慢)網絡共享和網絡份額在複製過程中已經丟失了好幾次。只要網絡共享再次可用,我就可以恢復複製。你應該可以做一些類似的日誌文件...

+4

這不是答案。如果網絡永不回來怎麼辦?現在你的程序被掛在忙碌的循環中。 FWIW不需要使用老式的文件API,該代碼可以用TFileStream輕鬆編寫。 –

+0

我爲此設計的代碼具有最大重試次數,因此它不會在繁忙循環中被鎖定;這很容易添加。我不知道TFileStream和舊式文件API是否處理了不同的事情,如果這可能是問題的一部分。因爲我知道它適用於文件API,所以我希望Simon知道該選項的工作原理。 –