2010-02-15 22 views
19

मेरे पास एक ऐसी प्रक्रिया है जिसे क्रॉन से अक्सर उस फ़ाइल को पढ़ने के लिए कहा जाएगा जिसमें कुछ चाल संबंधित कमांड हैं। मेरी प्रक्रिया को इस डेटा फ़ाइल को पढ़ने और लिखने की आवश्यकता है - और इस प्रक्रिया के दौरान अन्य प्रक्रियाओं को छूने से रोकने के लिए इसे लॉक रखें। उपयोगकर्ता द्वारा (संभावित) लिखने/उसी डेटा फ़ाइल में संलग्न करने के लिए एक पूरी तरह से अलग प्रक्रिया निष्पादित की जा सकती है। मैं इन दो प्रक्रियाओं को अच्छा खेलना चाहता हूं और एक ही समय में फ़ाइल को एक्सेस कर सकता हूं।पढ़ने और लिखने के लिए जावा फ़ाइल लॉक

एनओओ फ़ाइल लॉक मुझे जो चाहिए (मेरी खुद की सैमफोर प्रकार फाइलों को लिखने से कम) लग रहा था, लेकिन मुझे पढ़ने के लिए इसे लॉक करने में समस्या हो रही है। मैं बस ठीक से लॉक और लिख सकता हूं, लेकिन जब पढ़ने के दौरान लॉक बनाने का प्रयास करता हूं तो मुझे एक गैर-योग्य ChannelException मिलता है। क्या फ़ाइल पढ़ने के लिए लॉक करना भी संभव है? ऐसा लगता है कि RandomAccessFile की आवश्यकता के करीब है, लेकिन मुझे नहीं लगता कि इसे कैसे कार्यान्वित किया जाए।

FileInputStream fin = new FileInputStream(f); 
FileLock fl = fin.getChannel().tryLock(); 
if(fl != null) 
{ 
    System.out.println("Locked File"); 
    BufferedReader in = new BufferedReader(new InputStreamReader(fin)); 
    System.out.println(in.readLine()); 
      ... 

अपवाद FileLock लाइन पर फेंक दिया जाता है:

यहाँ कोड है कि विफल रहता है।

java.nio.channels.NonWritableChannelException 
at sun.nio.ch.FileChannelImpl.tryLock(Unknown Source) 
at java.nio.channels.FileChannel.tryLock(Unknown Source) 
at Mover.run(Mover.java:74) 
at java.lang.Thread.run(Unknown Source) 

Javadocs को देखते हुए, यह

अनियंत्रित अपवाद है जब एक प्रयास एक चैनल है कि मूल रूप लेखन के लिए नहीं खोला गया था करने के लिए लिखने के लिए किया जाता है फेंक दिया कहते हैं।

लेकिन मुझे इसे लिखने की आवश्यकता नहीं है। जब मैं लेखन उद्देश्यों के लिए FileOutpuStream आदि बनाने का प्रयास करता हूं, तब तक यह तब तक खुश होता है जब तक कि मैं एक ही फ़ाइल पर FileInputStream खोलने का प्रयास नहीं करता।

+0

क्या आपने तीन पैरा विधि कॉल, फ़ाइल लॉक लॉक (लंबी स्थिति, लंबा आकार, बूलियन साझा) का उपयोग करने का प्रयास किया है? मैंने पहले कभी भी फ़ाइल लॉक का उपयोग नहीं किया है, इसलिए मैं उत्तर के रूप में पोस्ट नहीं करूंगा लेकिन मुझे लगता है कि उस विधि कॉल का उपयोग करने से मदद मिल सकती है क्योंकि ऐसा लगता है कि आपको साझा लॉक की आवश्यकता है और एक विशेष लॉक नहीं है क्योंकि आप फ़ाइल को लिखना चाहते हैं उस पर एक ताला है। – ChadNC

+0

मुझे लगता है कि इसका इरादा केवल फाइल के हिस्सों को लॉक करना है, हालांकि मैं पूरी फाइल को रोकने और संभव भ्रष्टाचार को लॉक करना चाहता हूं। – bobtheowl2

उत्तर

16

(ए) क्या आप जानते हैं कि फ़ाइल को लॉक करने से अन्य प्रक्रियाओं को तब तक स्पर्श नहीं किया जाएगा जब तक कि वे ताले का उपयोग न करें?
(बी) आपको एक लिखने योग्य चैनल के माध्यम से लॉक करना होगा। "आरडब्ल्यू" मोड में RandomAccessFile के माध्यम से लॉक प्राप्त करें और फिर अपना FileInputStream खोलें। दोनों को बंद करना सुनिश्चित करें!

+1

ए) हां, मैं दोनों में समान लॉकिंग प्रक्रियाओं को लागू करने के लिए दोनों प्रक्रियाओं और योजना लिख ​​रहा हूं b) मुझे नहीं पता था कि आप सीधे RandomAccessFile पर लॉक प्राप्त कर सकते हैं। फ़ाइल [इनपुट | आउटपुट] स्ट्रीम का उपयोग करने के लिए मुझे एक नया FileInputStream (raf.getFD()) करने की आवश्यकता है। लेकिन, किसी भी तरह से RandomAccessFile ऑब्जेक्ट की इनपुट स्ट्रीम का उपयोग करके, मैं अभी भी फ़ाइल से पढ़ सकता हूं। धन्यवाद – bobtheowl2

+0

एह? (ए) आप सीधे RandomAccessFile से लॉक नहीं प्राप्त कर सकते हैं, आपको पहले फ़ाइल फ़ाइल को प्राप्त करना होगा; (बी) RandomAccessFile में इनपुट स्ट्रीम नहीं हैं, लेकिन यह डेटा इनपुट लागू करता है ताकि आप इसे सीधे से पढ़ सकें। – EJP

10

यदि आप tryLock(0L, Long.MAX_VALUE, true) का उपयोग कर लॉक बनाते हैं तो यह बेहतर होगा।

यह एक साझा लॉक बनाता है जो पढ़ने के लिए सही काम है।

tryLock()tryLock(0L, Long.MAX_VALUE, false) के लिए एक शॉर्टेंड है, यानी यह एक विशेष लेखन-लॉक का अनुरोध करता है।

+0

ग्रेट प्रतिक्रिया। यह कार्यक्रम पहले से ही लाइव है, लेकिन यह निश्चित रूप से अगले चरण में अपडेट किया जा सकता है।हम अब इसका इतना उपयोग देख रहे हैं कि विशिष्ट परिदृश्य कुछ विशेष परिस्थितियों में बोझिल हो रहे हैं। मैं निश्चित रूप से अगले अपडेट के लिए इसे ध्यान में रखूंगा। – bobtheowl2

+0

आप क्यों कहते हैं कि एक साझा लॉक पढ़ने के लिए सही काम है, निश्चित रूप से यह आपके उपयोग-मामले पर निर्भर करता है? अगर मैं यह सुनिश्चित करना चाहता हूं कि कई प्रक्रियाओं में से केवल 1 फ़ाइल को पढ़ती है (उदाहरण के लिए नई फाइलों को संसाधित करने के लिए एक अपलोड निर्देशिका की निगरानी करने वाले एजेंट) तो मुझे नहीं लगता कि साझा लॉक मुझे चाहिए। – codebox

+1

मैंने इसे इस तरह लिखा क्योंकि पढ़ना पारस्परिक रूप से अनन्य नहीं है। लेखन के दौरान एक फ़ाइल से कई धागे पढ़ने के लिए वास्तव में संभव है जब लेखन हमेशा अनन्य होता है। ध्यान रखें कि यह मूल प्रश्न का उत्तर था और हर स्थिति के लिए पूर्ण सत्य के रूप में नहीं है। हालांकि 99% उपयोग मामलों में यह सच है। – Huxi

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