Win32

2009-11-17 15 views
5

के साथ पढ़ने के लिए फ़ाइल उपलब्ध होने तक प्रतीक्षा कर रहा है, मैं ReadDirectoryChangesW को सिंक्रनाइज़ करके कॉल करके एक निर्देशिका देख रहा हूं। जब कोई नई फ़ाइल उपलब्ध होती है, तो मैं इसे CreateFileGENERIC_READ और FILE_SHARE_READ के साथ तुरंत एक्सेस करने का प्रयास करता हूं, लेकिन यह मुझे ERROR_SHARING_VIOLATION देता है। जिस प्रक्रिया को फ़ाइल को देखे गए निर्देशिका में रखा गया है, वह उस समय तक लिखना समाप्त नहीं करता जब तक मैं इसे पढ़ने की कोशिश नहीं करता।Win32

क्या फ़ाइल पढ़ने के लिए उपलब्ध होने तक विश्वसनीय रूप से प्रतीक्षा करने का कोई तरीका है? मैं विधि को नीचे की तरह एक लूप में डाल सकता हूं, लेकिन मुझे उम्मीद है कि एक बेहतर तरीका है।

while ((hFile = CreateFile (path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) 
{ 
    if (GetLastError() == ERROR_SHARING_VIOLATION) 
     Sleep (500); 
    else 
     break; // some other error occurred 
} 

if (hFile == INVALID_HANDLE_VALUE) 
{ 
    // deal with other error 
    return 0; 
} 

ReadFile (...); 
+0

मुझे लगता है कि यह सी ++ है? यदि यह सी # है, तो बीसीएल में एक SystemFileWatcher ऑब्जेक्ट है जिसका आप उपयोग कर सकते हैं। –

+0

Win32 == सी एपीआई, मैं पीछे हट जाऊंगा। – dreamlax

उत्तर

2

कोई बंद फ़ाइल पर अधिसूचनाओं के लिए कोई उपयोगकर्ता-मोड API नहीं है जिसे मैं जानता हूं। आपके द्वारा प्रस्तावित लूप वास्तव में शायद सबसे अच्छा तरीका है। एकमात्र अन्य चीज जो आप कर सकते हैं, एक फ़िल्टर ड्राइवर एला प्रोसेस मॉनिटर में क्लोजफाइल के लिए देखना होगा, लेकिन यक ...

0

अगर आपको फ़ाइल बनाने के तरीके के बारे में कुछ पता है, तो हो सकता है कि फ़ाइल एक्स के लिए बढ़ती रहती है सेकेंड, या एक सेंटीनेल फ़ाइल हटा दिए जाने तक प्रतीक्षा करें। या प्रोग्राम की स्थिति को समझें जो उन्हें बनाता है।

+0

दुर्भाग्य से मुझे इस बारे में कोई जानकारी नहीं है कि फ़ाइल कैसे उत्पन्न होती है या प्रक्रिया जो इसे देखे गए फ़ोल्डर में डाल रही है (यह कोई प्रोग्राम हो सकता है, या यह उपयोगकर्ता फ़ाइल को खींच और छोड़ सकता है, आदि)। – dreamlax

5

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

int delay= 10; 
while ((hFile = CreateFile (path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) 
{ 
    if (GetLastError() == ERROR_SHARING_VIOLATION) { 
     Sleep (delay); 
     if (delay<5120) // max delay approx 5.Sec 
      delay*= 2; 
    } 
    else 
     break; // some other error occurred 
} 
2

रूप @Matt डेविस ने कहा, दुर्भाग्य से कोई उपयोगकर्ता के मोड एपीआई है लेकिन वहाँ एक समाधान है कि आपके यूज-केस के आधार पर (मैं मेरा नीचे लिखा है) बस ऐसा कर सकते हैं कि आप क्या चाहते है।

क्या अतीत में मेरे लिए काम किया FILE_NOTIFY_CHANGE_LAST_WRITEबजायFILE_NOTIFY_CHANGE_FILE_NAME के लिए पंजीकरण किया गया था जब ReadDirectoryChangesW बुला:

ZeroMemory(&overlapped, sizeof(OVERLAPPED)); 
overlapped.hEvent = hChangeEvent; 

// ...  
ReadDirectoryChangesW(hSpoolPath, 
         eventBuffer, 
         EVENT_BUF_LENGTH, 
         FALSE, 
         FILE_NOTIFY_CHANGE_LAST_WRITE, // <---- 
         NULL, 
         &overlapped, 
         NULL); 
// ... 
HANDLE events[2]; 

events[0] = hChangeEvent; 
events[1] = hCancelEvent; 

DWORD wRc = WaitForMultipleObjects(2, events, FALSE, DIRECTORY_WATCH_TIMEOUT); 

पिछले लिखने समय जैसे ही मालिक प्रक्रिया फ़ाइल बनाने के बाद बंद कर देता है संभाल के रूप में अद्यतन हो जाता है और इसे लिखना।

मेरा उपयोग-मामला एक प्रक्रिया थी जिसे टीसीपी/आईपी के माध्यम से HTTP-अनुरोध प्राप्त हुए और HTTP-body को एक निर्देशिका में लिखा, जहां एक और प्रक्रिया इसे प्राप्त करने के तुरंत बाद प्राप्त की गई प्रक्रिया (और इसके परिणामस्वरूप बंद करना इसे संभालें। Http-server एकमात्र प्रक्रिया थी जो उस निर्देशिका को लिखी गई थी, इसलिए मैं निर्माण-लिखने-बंद पैटर्न पर भरोसा कर सकता था।

+0

ReadDirectoryChangesW FILE_NOTIFY_CHANGE_LAST_WRITE के लिए साइन अप करते समय मुझे दो बार सूचित करता है और फिर फ़ोल्डर में फ़ाइल जोड़ता है। आपने किस अधिसूचना का उपयोग किया था? – Will

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