2009-03-16 15 views
7

क्या एक फ़ाइल को इस तरह से खोलना संभव है जिससे उसके मूल फ़ोल्डर को बाद में हटाने/नामांकन की अनुमति मिल सके?बिना खुले फ़ाइल (वास्तव में) इसे लॉक कर रहा है?

मैं जानता हूँ कि आप यह कर सकते हैं: जब फ़ाइल हैंडल बंद कर दिया है

File.Open("foo.bar", FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete) 

किन फ़ाइल के लिए अनुमति देगा हटाए जाने के लिए। हालांकि, अगर यह त्रुटि के बिना मूल फ़ोल्डर को हटाने की अनुमति नहीं देता है।

मुझे ढांचे में कुछ भी नहीं मिला। क्या मैंने कुछ अनदेखा किया है, या कोई मूल एपीआई है जिसे मैं इंटरऑप कर सकता हूं।

नोट: मुझे हटाया नहीं गया है कि हटाए गए फ़ाइल की स्ट्रीम का उपयोग करते समय मुझे अपवाद मिलता है। वास्तव में यह आदर्श होगा।

अद्यतन:

तो सबसे होनहार विचार Hardlink था, हालांकि मैं सिर्फ यह काम नहीं कर सकता। जब भी मैं मूल निर्देशिका को हटाने का प्रयास करता हूं तब भी मैं एक्सेस अस्वीकृत हो जाता हूं। यहां मेरा कोड है:

class Program 
{ 
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    static extern bool CreateHardLink(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes); 

    static void Main(string[] args) 
    { 
     string hardLinkPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); 
     string realPath = @"C:\foo\bar.txt"; 
     if (CreateHardLink(hardLinkPath, realPath, IntPtr.Zero)) 
     { 
      using (FileStream stream = File.Open(hardLinkPath, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite)) 
      { 
       Console.Write("File locked"); 
       Console.ReadLine(); 
      } 

      File.Delete(hardLinkPath); 
     } 
     else 
      Console.WriteLine("LastError:{0}", Marshal.GetLastWin32Error()); 
    } 
} 

उत्तर

0

सबसे अच्छा समाधान मैं साथ आ सकता हूं, फ़ाइल को अस्थायी स्क्रैच स्थान पर कॉपी करना है। फिर, temp फ़ाइल खोलें, और समाप्त होने पर इसे हटा दें।

+0

ऐसा कुछ लगता है जो मैं करता हूं। यदि फ़ाइल पर्याप्त छोटा है तो हो सकता है कि आप स्मृति में प्रतिलिपि बना सकें? – strager

+0

हाँ, हम अब ऐसा कर रहे हैं, लेकिन बहुत सारी फाइलें हैं, और वे काफी बड़े हैं 3 एमबी से 100 एमबी। यह बहुत सी जीसी थ्रैशिंग का कारण बनता है। –

0

FileOpen Kernel32.dll में CreateFile का उपयोग करता है। मुझे यकीन नहीं है कि आप .NET Framework से अधिक कुछ हासिल करने में सक्षम होंगे, क्योंकि सभी विकल्प पहले से ही हैं, जब तक कि आप इसे transaction के रूप में निष्पादित न करें।

+0

मैं अब प्रलेखन के माध्यम से मछली पकड़ रहा हूँ। क्या आपको पता है कि CreateFileTransacted के साथ खोला गया फ़ाइल, पैरेंट फ़ोल्डर को हटाने की अनुमति देता है, या आप इसे सिर्फ एक विकल्प के रूप में सुझाव दे रहे हैं? –

+0

मुझे लगता है कि फाइल पर काम करने वाले 2 थ्रेड हैं, एक खोलने के लिए और एक ही समय में हटाने की कोशिश कर रहा है? –

+0

अंत में, लेकिन मैं केवल उनमें से एक को नियंत्रित करता हूं। –

1

यदि आप एनटीएफएस के साथ काम कर रहे हैं तो आप अस्थायी स्थान पर फ़ाइल में एक और हार्डलिंक बना सकते हैं, तो आप फाइल कॉपी ओवरहेड से बचेंगे, और पहला लिंक अभी भी हटाया जा सकता है (या तो फाइल स्वयं या एक युक्त निर्देशिका) दूसरे को प्रभावित किए बिना।

+0

हम्म, यह बहुत ही आशाजनक प्रतीत होता है, हालांकि जब भी मैंने मूल फ़ोल्डर हटा दिया तो मुझे अभी भी त्रुटि मिलती है। शायद मैं कुछ गलत कर रहा हूँ। क्या आपने यह कोशिश की है? –

+0

हार्ड लिंक मूल फ़ाइल के समान होना चाहिए, यानी, फ़ाइल में "मुख्य" पॉइंटर की वास्तव में अवधारणा नहीं है, वे सभी समान रूप से काम करते हैं। (यह एक और निर्देशिका सूचक जोड़ता है) मैंने व्यक्तिगत रूप से इन सटीक परिस्थितियों में उनका उपयोग नहीं किया है, लेकिन इसे काम करना चाहिए ... – Eric

+0

मैंने जो कोड जोड़ा है, उसे देखें, यह मामला प्रतीत नहीं होता है। –

संबंधित मुद्दे