2012-03-08 9 views
8

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

पूर्ण रेपो https://github.com/davidebbo/NpmFolderRenameIssue पर पाया जा सकता है।

// This file doesn't exist yet 
// Note that the presence of this existence check is what triggers the bug below!! 
Console.WriteLine("Exists (should be false): " + File.Exists("test/test2/myfile")); 

// Create a directory, with a file in it 
Directory.CreateDirectory("test/subdir/test"); 
File.WriteAllText("test/subdir/test/myfile", "Hello"); 

// Rename the directory 
Directory.Move("test/subdir/test", "test/test2"); 

var start = DateTime.UtcNow; 

// List the files at the new location. Here, our file shows up fine 
foreach (var path in Directory.GetFiles("test/test2")) 
{ 
    Console.WriteLine(path); 
} 

for (; ;) 
{ 
    // Now do a simple existence test. It should also be true, but when 
    // running on a (cross machine) UNC share, it takes almost 5 seconds to become true! 
    if (File.Exists("test/test2/myfile")) break; 

    Console.WriteLine("After {0} milliseconds, test/test2/myfile doesn't show as existing", 
     (DateTime.UtcNow - start).TotalMilliseconds); 
    Thread.Sleep(100); 
} 

Console.WriteLine("After {0} milliseconds, test/test2/myfile correctly shows as existing!", 
    (DateTime.UtcNow - start).TotalMilliseconds); 

तो यह प्रारंभिक अस्तित्व की जांच की तरह लगता है, कैश हो जाने की इस फर्जी व्यवहार के कारण अस्तित्व मूल्य का कारण बनता है: यहाँ कोर कोड है।

प्रश्न: इसके लिए स्पष्टीकरण क्या है? इससे बचने का सबसे अच्छा तरीका क्या है?

नोट: विंडोज़ पर एनपीएम (नोड पैकेज मैनेजर) का उपयोग करते समय यह समस्या शुरू में उभरी। मेरे पास यहां मौजूद कोड रेपो का सी # पोर्ट है। मूल नोड/एनपीएम मुद्दे के लिए https://github.com/isaacs/npm/issues/2230 देखें। लक्ष्य इसे संबोधित करने का एक तरीका ढूंढना है।

+1

ध्यान दें कि 'फ़ाइल.इक्सिस्ट' को कॉल करने से संभावित दौड़ की स्थिति हल नहीं होगी। मुझे यकीन नहीं है कि यह यहां भी जरूरी है। 'File.Exists' के जवाब में आप जो कुछ भी कर रहे हैं, आप बस अपवाद के जवाब में ही कर सकते हैं। –

+1

आप इस तरह के व्यवहार को सभी प्रकार के नेटवर्क फाइल सिस्टम के साथ देख सकते हैं हालांकि Win7 कितना समय तक कैश किया गया है ... Win2k8 के साथ मैं इसे बहुत ही कम देखता हूं जबकि Win7 के साथ यह "नियमित" है ... मुझे कुछ एमएस पर संदेह है फाइल सिस्टम देव आपके प्रश्न का उत्तर दे सकता है ... एसओ पर कुछ मदद पाने के लिए आपको अपने लक्ष्य का अधिक स्पष्ट रूप से वर्णन करना होगा आईएमओ ... – Yahia

+0

@ कोडी: ध्यान दें कि मैं आपका अनुसरण कर रहा हूं। यह File.Exists के लिए उचित लगता है यदि निर्देशिका.GetFiles() इसे सूचीबद्ध करता है, नहीं? –

उत्तर

10

डेविड, पुनर्निर्देशक एक नकारात्मक "फ़ाइल नहीं मिला" कैश लागू करता है जो किसी क्लाइंट को फ़ाइल के अनुरोध के साथ सर्वर को बाढ़ करने से रोकता है। डिफ़ॉल्ट कैश समय 5 सेकंड है, लेकिन आप कैश को नियंत्रित करने के लिए या 0.

विवरण इस मूल्य निर्धारित करके उसे निष्क्रिय करने FileNotFoundCacheLifetime रजिस्ट्री मान को संशोधित कर सकते हैं: http://technet.microsoft.com/en-us/library/ff686200(v=WS.10).aspx

+1

हाँ, यह वास्तव में है! इस FileNotFoundCacheLifetime मान को 0 पर सेट करना उस स्थिति को हटा देता है। बेशक, सिस्टम पर नकारात्मक perf implication हो सकता है, तो यह करने के लिए एक स्मार्ट बात नहीं हो सकती है। लेकिन मैं ज्यादातर ऐसा कुछ ढूंढ रहा था जो व्यवहार को समझाता है, और ऐसा करता है। धन्यवाद! –

1

नेटवर्क कोड में कैशिंग के कई स्तर हैं। यह फ़ाइल अस्तित्व के आखिरकार दिखाए जाने के समय को धीमा कर सकता है।

एक समाधान फ़ाइल शेयरों का उपयोग नहीं करना होगा, लेकिन एक साधारण क्लाइंट/सर्वर आर्किटेक्चर बनाना होगा जहां सर्वर स्थानीय फ़ाइल सिस्टम से फ़ाइल अस्तित्व लौटाता है। यह वास्तव में आइटम पहचान समय तेज करना चाहिए।

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

+1

दरअसल, फ़ाइल खोली जा सकती है। अन्य उत्तर देखें; यह एक दस्तावेज अस्तित्व कैशिंग सुविधा के कारण होता है। –

1

एक बार मैं के बारे में "फ़ाइल नहीं मिला" जानता था कैश, मैं FileInfo ऑब्जेक्ट का उपयोग कर समस्या को हल करने में सक्षम था, जो Refresh() विधि लागू करता है। आपका कोड इसके बजाय ऐसा कर सकता है:

FileInfo testFile = new FileInfo("test/test2/myfile"); 
Console.WriteLine("Exists (should be false): " + testFile .Exists); 
Directory.Move("test/subdir/test", "test/test2"); 
testFile.Refresh(); 

// the FileInfo object should now be refreshed, and a second call to Exists will return a valid value 
if (testFile.Exists) 
{ 
    ... 
} 
संबंधित मुद्दे