इससे पहले, हमें IO API (इनपुट/आउटपुट एप्लिकेशन प्रोग्रामिंग इंटरफ़ेस) और java.io पैकेज के बारे में पता चला , जिनकी कक्षाएं मुख्य रूप से Java में स्ट्रीम के साथ काम करने के लिए हैं। यहाँ कुंजी धारा की अवधारणा है ।

आज हम NIO API (न्यू इनपुट/आउटपुट) पर विचार करना शुरू करेंगे।

I/O के दो दृष्टिकोणों के बीच मुख्य अंतर यह है कि IO API स्ट्रीम-ओरिएंटेड है जबकि NIO API बफर-ओरिएंटेड है। तो समझने के लिए मुख्य अवधारणाएँ बफ़र्स और चैनल हैं ।

बफर क्या है और चैनल क्या है?

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

दूसरे शब्दों में:

  • बफ़र केवल मेमोरी का एक ब्लॉक है जिसमें हम जानकारी लिख सकते हैं और जिससे हम जानकारी पढ़ सकते हैं ,
  • एक चैनल एक गेटवे है जो I/O डिवाइस जैसे फाइल या सॉकेट तक पहुंच प्रदान करता है।

चैनल java.io पैकेज में स्ट्रीम के समान हैं। सभी डेटा जो कहीं भी जाता है (या कहीं से भी आता है) एक चैनल ऑब्जेक्ट से गुजरना चाहिए। सामान्य तौर पर, NIO सिस्टम का उपयोग करने के लिए, आपको I/O इकाई के लिए एक चैनल और डेटा स्टोर करने के लिए एक बफर मिलता है। फिर आप बफर के साथ काम करते हैं, आवश्यकतानुसार डेटा इनपुट या आउटपुट करते हैं।

आप बफ़र में आगे और पीछे जा सकते हैं, यानी बफ़र को "वॉक" कर सकते हैं, जो कुछ ऐसा है जो आप स्ट्रीम में नहीं कर सकते। डेटा संसाधित करते समय यह अधिक लचीलापन देता है। मानक पुस्तकालय में, बफ़र्स को अमूर्त बफ़र वर्ग और उसके कई वंशजों द्वारा दर्शाया जाता है:

  • बाइटबफ़र
  • चारबफर
  • शॉर्टबफर
  • इंटबफर
  • फ्लोटबफर
  • डबलबफ़र
  • लॉन्गबफर

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

बफर गुण

एक बफ़र में चार मुख्य गुण होते हैं। ये क्षमता, सीमा, स्थिति और चिह्न हैं।

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

राइट मोड में, बफ़र की सीमा उसकी क्षमता के समान होती है, जो बफ़र को लिखे जा सकने वाले डेटा की अधिकतम मात्रा को दर्शाता है। रीड मोड में, बफ़र की सीमा डेटा की अधिकतम मात्रा को संदर्भित करती है जिसे बफ़र से पढ़ा जा सकता है।

स्थिति बफर में कर्सर की वर्तमान स्थिति को इंगित करती है प्रारंभ में, यह 0 पर सेट होता है जब बफर बनाया जाता है। दूसरे शब्दों में, यह पढ़ने या लिखे जाने वाले अगले तत्व का सूचकांक है।

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

बफर के साथ काम करने के तरीके

अब आइए उन तरीकों के मुख्य सेट को देखें जो हमें चैनलों से डेटा पढ़ने और लिखने के लिए हमारे बफर (मेमोरी ब्लॉक) के साथ काम करते हैं।

  1. आबंटन (पूर्णांक क्षमता) - इस विधि का उपयोग निर्दिष्ट क्षमता के साथ एक नया बफर आवंटित करने के लिए किया जाता है। आवंटित () विधि एक IllegalArgumentException फेंकता है यदि पारित क्षमता एक नकारात्मक पूर्णांक है।

  2. क्षमता () वर्तमान बफर की क्षमता लौटाती है ।

  3. स्थिति () वर्तमान कर्सर स्थिति लौटाती है। पढ़ें और लिखें ऑपरेशन कर्सर को बफर के अंत में ले जाते हैं। वापसी मान हमेशा सीमा से कम या उसके बराबर होता है।

  4. सीमा () वर्तमान बफ़र की सीमा लौटाती है।

  5. चिह्न () का उपयोग वर्तमान कर्सर स्थिति को चिह्नित करने (सहेजने) के लिए किया जाता है।

  6. रीसेट () कर्सर को पहले से चिह्नित (सहेजी गई) स्थिति में लौटाता है।

  7. clear() स्थिति को शून्य पर सेट करता है और क्षमता की सीमा निर्धारित करता है। यह विधि बफ़र में डेटा साफ़ नहीं करती है । यह केवल स्थिति, सीमा और चिह्न को पुन: प्रारंभ करता है।

  8. फ्लिप () बफर को राइट मोड से रीड मोड में स्विच करता है। यह वर्तमान स्थिति की सीमा भी निर्धारित करता है और फिर स्थिति को वापस शून्य पर रखता है।

  9. रीड () - चैनल की रीड विधि का उपयोग चैनल से बफर में डेटा लिखने के लिए किया जाता है, जबकि बफर की पुट () विधि का उपयोग बफर में डेटा लिखने के लिए किया जाता है।

  10. राइट () - चैनल की राइट मेथड का उपयोग बफर से चैनल में डेटा लिखने के लिए किया जाता है, जबकि बफर के गेट () मेथड का उपयोग बफर से डेटा पढ़ने के लिए किया जाता है।

  11. रिवाइंड () बफर को रिवाइंड करता है। इस पद्धति का उपयोग तब किया जाता है जब आपको बफ़र को फिर से पढ़ने की आवश्यकता होती है - यह स्थिति को शून्य पर सेट करता है और सीमा को नहीं बदलता है।

और अब चैनलों के बारे में कुछ शब्द।

Java NIO में सबसे महत्वपूर्ण चैनल कार्यान्वयन निम्न वर्ग हैं:

  1. FileChannel — फ़ाइल से/में डेटा पढ़ने और लिखने के लिए एक चैनल।

  2. डेटाग्राम चैनल - यह वर्ग यूडीपी (उपयोगकर्ता डेटाग्राम प्रोटोकॉल) के माध्यम से नेटवर्क पर डेटा पढ़ता और लिखता है।

  3. सॉकेटचैनल - टीसीपी (ट्रांसमिशन कंट्रोल प्रोटोकॉल) के माध्यम से नेटवर्क पर डेटा पढ़ने और लिखने के लिए एक चैनल।

  4. ServerSocketChannel — टीसीपी कनेक्शन पर डेटा पढ़ने और लिखने के लिए एक चैनल, जैसा कि एक वेब सर्वर करता है। प्रत्येक आने वाले कनेक्शन के लिएएक सॉकेटचैनल बनाया जाता है।

अभ्यास

कोड की कुछ पंक्तियाँ लिखने का समय आ गया है। सबसे पहले, फ़ाइल को पढ़ते हैं और इसकी सामग्री को कंसोल पर प्रदर्शित करते हैं, और फिर फ़ाइल में कुछ स्ट्रिंग लिखते हैं।

कोड में बहुत सारी टिप्पणियाँ हैं - मुझे आशा है कि वे आपको यह समझने में मदद करेंगी कि सब कुछ कैसे काम करता है:


// Create a RandomAccessFile object, passing in the file path
// and a string that says the file will be opened for reading and writing
try (RandomAccessFile randomAccessFile = new RandomAccessFile("text.txt", "rw");
    // Get an instance of the FileChannel class
    FileChannel channel = randomAccessFile.getChannel();
) {
// Our file is small, so we'll read it in one go   
// Create a buffer of the required size based on the size of our channel
   ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
   // Read data will be put into a StringBuilder
   StringBuilder builder = new StringBuilder();
   // Write data from the channel to the buffer
   channel.read(byteBuffer);
   // Switch the buffer from write mode to read mode
   byteBuffer.flip();
   // In a loop, write data from the buffer to the StringBuilder
   while (byteBuffer.hasRemaining()) {
       builder.append((char) byteBuffer.get());
   }
   // Display the contents of the StringBuilder on the console
   System.out.println(builder);
 
   // Now let's continue our program and write data from a string to the file
   // Create a string with arbitrary text
   String someText = "Hello, Amigo!!!!!";
   // Create a new buffer for writing,
   // but let the channel remain the same, because we're going to the same file
   // In other words, we can use one channel for both reading and writing to a file
   // Create a buffer specifically for our string — convert the string into an array and get its length
   ByteBuffer byteBuffer2 = ByteBuffer.allocate(someText.getBytes().length);
   // Write our string to the buffer
   byteBuffer2.put(someText.getBytes());
   // Switch the buffer from write mode to read mode
   // so that the channel can read from the buffer and write our string to the file
   byteBuffer2.flip();
   // The channel reads the information from the buffer and writes it to our file
   channel.write(byteBuffer2);
} catch (FileNotFoundException e) {
   e.printStackTrace();
} catch (IOException e) {
   e.printStackTrace();
}

NIO API आज़माएं — आपको यह पसंद आएगा!