2012-08-23 7 views
5

मैं TFilestream का उपयोग कर नेटवर्क शेयर (स्थानीय) पर लिखने का प्रयास करता हूं। नेटवर्क कनेक्शन को हस्तक्षेप नहीं किया जाना चाहिए यह सब ठीक काम करता है।TFilestream का उपयोग कर नेटवर्क साझा करने के लिए डेल्फी लेखन फ़ाइल खो जाने पर फ़ाइल को ताला लगा देता है

हालांकि, अगर मैं नेटवर्क केबल खींचता हूं और फिर इसे फिर से कनेक्ट करता हूं, तो प्रवेश प्रतिबंधों के कारण फ़ाइलस्ट्रीम खोलने के बाद के प्रयास विफल हो जाते हैं। मैं एक्सप्लोरर में फ़ाइल को भी हटा नहीं सकता! ऐसा लगता है कि 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 की तरह कुछ और उपयोग करें। –

उत्तर

7

Network Share API, NetFileEnum और NetFileClose फ़ंक्शंस का उपयोग करके अपनी फ़ाइल को बंद करने का प्रयास करें। यह भी देखें a related question

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

यह उत्तर नहीं है। क्या होगा यदि नेटवर्क कभी वापस नहीं आएगा? अब आप एक व्यस्त पाश में लटका दिया गया है। एफडब्ल्यूआईडब्ल्यू को पुराने फैशन फ़ाइल एपीआई का उपयोग करने की आवश्यकता नहीं है, वह कोड आसानी से TFileStream के साथ लिखा जा सकता है। –

+0

जिस कोड से मैंने इसे पैटर्न किया है, उसके पास अधिकतम रीट्री गिनती है ताकि यह व्यस्त लूप में लॉक न हो; जोड़ना आसान है। मुझे नहीं पता था कि TFileStream और पुरानी शैली वाली फ़ाइल एपीआई ने चीजों को अलग-अलग संभाला है और यदि यह समस्या का हिस्सा हो सकता है। चूंकि मुझे पता है कि यह फ़ाइल एपीआई के साथ काम करता है, मैं चाहता था कि साइमन यह जान सके कि वह विकल्प कैसे काम करता है ... –