CodeGym /Java Blog /এলোমেলো /কীবোর্ড থেকে পড়া: "পাঠক"
John Squirrels
লেভেল 41
San Francisco

কীবোর্ড থেকে পড়া: "পাঠক"

এলোমেলো দলে প্রকাশিত
ওহে! লেভেল 3-এর পাঠ এবং কাজগুলি আপনাকে শিখিয়েছে কীভাবে কনসোলে স্টাফ প্রদর্শন করতে হয়, এবং, অন্য দিকে যেতে, কীভাবে কীবোর্ড থেকে ডেটা পড়তে হয়।
কীবোর্ড থেকে পড়া: "পাঠক" - 1
এমনকি আপনি এটি সম্পন্ন করতে নিম্নলিখিত জটিল গঠন ব্যবহার করতে শিখেছেন:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
কিন্তু একটা প্রশ্ন আছে যার উত্তর আমরা এখনো পাইনি।

কিভাবে বিশ্বের এই কাজ করে?

বাস্তবে, প্রোগ্রামগুলি খুব কমই সম্পূর্ণ স্বাধীন। তারা অন্যান্য প্রোগ্রাম, সিস্টেম, ইন্টারনেট ইত্যাদির সাথে যোগাযোগ করে। "যোগাযোগ" দ্বারা আমরা মূলত "ডেটা বিনিময়" বোঝায়। অর্থাৎ, তারা কিছু বাহ্যিক ডেটা গ্রহণ করে এবং কোথাও অভ্যন্তরীণ প্রোগ্রাম ডেটা পাঠায়। দৈনন্দিন জীবনে ডেটা আদান-প্রদানকারী প্রোগ্রামগুলির উদাহরণ প্রচুর। উদাহরণস্বরূপ, অনেক ওয়েবসাইট আপনাকে নিবন্ধনের পরিবর্তে আপনার Facebook বা Twitter অ্যাকাউন্ট ব্যবহার করে সাইন ইন করতে দেয়। এই পরিস্থিতিতে, দুটি প্রোগ্রাম (যেমন টুইটার এবং আপনি যে ওয়েবসাইটটিতে সাইন ইন করছেন) প্রয়োজনীয় ডেটা বিনিময় করে। চূড়ান্ত ফলাফল হল আপনি সফলভাবে সাইন ইন করেছেন৷ "স্ট্রীম" শব্দটিডেটা বিনিময় প্রক্রিয়া বর্ণনা করতে ব্যবহৃত হয়। এই নাম কোথা থেকে এসেছে? আপনার অভিজ্ঞতায়, একটি "স্ট্রিম" নদীগুলির সাথে এবং প্রোগ্রামিংয়ের চেয়ে বেশি যুক্ত হতে পারে। এটি কোন দুর্ঘটনা নয় :) একটি স্ট্রীম হল, সারমর্মে, ডেটার একটি চলমান অংশ। অন্য কথায়, প্রোগ্রামিং-এ, জল প্রবাহিত হয় না - বরং বাইট এবং অক্ষর আকারে ডেটা। আমরা একটি ডেটা স্ট্রিম থেকে ডেটার বিটগুলি গ্রহণ করতে পারি এবং তারপরে সেগুলি ব্যবহার করতে পারি। আবার, আমরা জল/প্রবাহের উপমা ব্যবহার করব: আপনি স্যুপ তৈরি করতে, আগুন নেভাতে বা আপনার ফুলগুলিতে জল দিতে একটি নদী থেকে জল স্কুপ করতে পারেন। স্ট্রীমগুলি আপনাকে যে কোনও ডেটা উত্সের সাথে কাজ করতে দেয়: ইন্টারনেট, আপনার কম্পিউটারের ফাইল সিস্টেম বা অন্য কিছু - এটি কোনও পার্থক্য করে না। স্ট্রিম একটি সার্বজনীন হাতিয়ার. তারা একটি প্রোগ্রামকে যেকোন জায়গা (ইনপুট স্ট্রীম) থেকে ডেটা গ্রহণ করতে এবং যেকোন জায়গায় (আউটপুট স্ট্রীম) পাঠানোর অনুমতি দেয়। তাদের কাজ একই: এক জায়গা থেকে ডেটা নিয়ে অন্য জায়গায় পাঠানো। দুই ধরনের প্রবাহ আছে:
  1. ইনপুট স্ট্রীমগুলি ডেটা গ্রহণ করতে ব্যবহৃত হয়
  2. আউটপুট স্ট্রীম ডেটা পাঠানোর জন্য।
জাভাতে, এই স্ট্রিমগুলি InputStreamএবং OutputStreamক্লাস দ্বারা প্রয়োগ করা হয়। তবে স্ট্রিমগুলিকে অন্যভাবে শ্রেণীবদ্ধ করা যেতে পারে। ইনপুট এবং আউটপুট স্ট্রীম ছাড়াও, আমরা বাইট স্ট্রীম এবং ক্যারেক্টার স্ট্রীম সম্পর্কেও কথা বলি । এখানে অর্থটি যথেষ্ট পরিষ্কার হওয়া উচিত: বাইট স্ট্রিম বাইটের সেট হিসাবে তথ্য পাঠায়, যখন একটি অক্ষর স্ট্রিম এটিকে অক্ষরের সেট হিসাবে পাঠায়। এই পাঠে, আমরা ইনপুট স্ট্রীমগুলিতে থাকব। আমি পাঠের শেষে আউটপুট স্ট্রীম সম্পর্কে তথ্য সহ একটি লিঙ্ক রাখব। আপনি নিজেই এটি পড়তে পারেন :) এখন এই কোডটি একবার দেখুন:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
পাঠের মধ্য দিয়ে যাওয়ার সময়, আপনি কি মনে করেননি যে এই লাইনটি মোটামুটি ভীতিজনক ছিল? :) আমরা এটা কিভাবে কাজ করে একবার অন্বেষণ করেছি যে ক্ষেত্রে হবে না. এর জিনিস ঠিক করা যাক. আমরা শেষে শুরু করব। System.inএকটি InputStreamঅবজেক্ট, ক্লাসের একটি উদাহরণ যা আমরা প্রথম দিকে বলেছিলাম। এটি একটি ইনপুট স্ট্রীম যা একটি সিস্টেম ইনপুট ডিভাইস (কীবোর্ড) এর সাথে সংযুক্ত। যাইহোক, আপনি এই প্রবাহের সাথে পরোক্ষভাবে পরিচিত। সর্বোপরি, আপনি প্রায়শই এর "সহকর্মী" ব্যবহার করেন — System.out! System.outসিস্টেম আউটপুট স্ট্রীম হয়। এটি আপনার পছন্দের পদ্ধতির মাধ্যমে কনসোলে ডেটা আউটপুট করতে ব্যবহৃত হয় System.out.println(), যা আপনি ক্রমাগত ব্যবহার করেন :) System.outকনসোলে ডেটা পাঠানোর জন্য একটি স্ট্রীম, যখনSystem.inকীবোর্ড থেকে ডেটা পাওয়ার জন্য। এটা সব সহজ :) আরো কি, আমরা এই বিশাল নির্মাণ ছাড়া কীবোর্ড থেকে তথ্য পড়তে পারেন. আমরা সহজভাবে লিখতে পারি: System.in.read();

public class Main {

   public static void main(String[] args) throws IOException {

       while (true) {
           int x = System.in.read();
           System.out.println(x);
       }
   }
}
ক্লাসে InputStream(মনে রাখবেন, System.inএকটি InputStreamবস্তু) একটি read()পদ্ধতি রয়েছে যা আপনাকে ডেটা পড়তে দেয়। একটি সমস্যা আছে: এটি বাইট পড়ে, অক্ষর নয় । শুধুমাত্র ইংরেজি অক্ষর ব্যবহার করা বিরক্তিকর তাই আসুন কীবোর্ড থেকে চীনা অক্ষর "魚" পড়ার চেষ্টা করি (শুধু এখান থেকে এই অক্ষরটি অনুলিপি করুন এবং PC এ ctrl + v বা Mac এ Command + v ব্যবহার করে কনসোলে পেস্ট করুন )। এই চরিত্রের অর্থ হল 'একটি মাছ'। কনসোল আউটপুট: 233 173 154 10 এই চিহ্ন এবং অন্যান্য অনেক চীনা কম্পিউটারের মেমরিতে 3 বাইট দখল করে (ল্যাটিন অক্ষরের বিপরীতে, যা মাত্র 1 বাইট দখল করে)। এই ক্ষেত্রে, স্ট্রিম থেকে 4 বাইট পড়া হয়: প্রথম তিনটি "魚" অক্ষরকে উপস্থাপন করে এবং অন্য বাইট একটি নতুন লাইন (এন্টার) প্রতিনিধিত্ব করে। তদনুসারে, System.inএর অশোভিত আকারে আমাদের জন্য একটি বিকল্প নয়। মানুষ (বিরল ব্যতিক্রম সহ!) বাইট পড়তে জানে না। কিন্তু InputStreamReaderক্লাস রেসকিউ আসে! চলুন দেখে নেই এটা কি ধরনের প্রাণী।

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
আমরা InputStreamReaderSystem.in অবজেক্টে পাস করি । ক্লাসের নামই বলে! আমরা একটি অবজেক্ট তৈরি করি এবং এটিকে একটি ইনপুট স্ট্রীম পাস করি যা থেকে এটি ডেটা পড়বে। এক্ষেত্রে... InputStreamReader

new InputStreamReader(System.in)
...আমরা এটাকে বলি, "আপনি সিস্টেম ইনপুট স্ট্রিম (কীবোর্ড থেকে) থেকে ডেটা পড়বেন"। কিন্তু এটি তার একমাত্র ফাংশন নয়! InputStreamReaderশুধুমাত্র স্ট্রীম থেকে ডেটা গ্রহণ করে না । এটি বাইট স্ট্রীমকে ক্যারেক্টার স্ট্রীমে রূপান্তর করে । অন্য কথায়, আপনাকে আর "এক এবং শূন্য" থেকে "মানব-পাঠযোগ্য ভাষা"-এ রূপান্তর করতে হবে না। InputStreamreaderআপনার জন্য সবকিছু করে। অবশ্যই, InputStreamReaderকনসোল থেকে ডেটা পড়ার মধ্যে সীমাবদ্ধ নয়। এটি অন্যান্য জায়গা থেকেও ডেটা পড়তে পারে। উদাহরণস্বরূপ, একটি ফাইল থেকে:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

   public static void main(String[] args) throws IOException {
       InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("C:\\Users\\username\\Desktop\\testFile.txt"));
   }
}
এখানে আমরা একটি FileInputStream(এর একটি ফ্লেভার InputStream) তৈরি করি, ফাইল পাথে পাস করি এবং স্ট্রীমটি নিজেই পাস করি InputStreamReader। এখন এটি ফাইল থেকে ডেটা পড়তে সক্ষম হবে (যদি একটি ফাইল আসলে পাথে বিদ্যমান থাকে তবে অবশ্যই)। আমরা ডেটা পড়ার জন্য InputStreamReaderক্লাসের read()পদ্ধতিও ব্যবহার করি (ডেটার উৎস কোন ব্যাপার না: কনসোল, একটি ফাইল বা অন্য কোথাও)। System.in.read()এবং এর মধ্যে পার্থক্য কি InputStreamReader.read()?\ আসুন আবার একটি দিয়ে "魚" অক্ষরটি পড়ার চেষ্টা করি InputStreamReader। আমি আপনাকে মনে করিয়ে দিচ্ছি যে আসলে কী পড়েছিল System.in.read(): 233 173 154 10 এবং কীভাবে InputStreamReaderএকই কাজ করে?

public class Main {

   public static void main(String[] args) throws IOException {

       InputStreamReader reader = new InputStreamReader(System.in);
       while (true) {
           int x = reader.read();
           System.out.println(x);
       }
   }
}
কনসোল আউটপুট: 39770 10 পার্থক্যটি অবিলম্বে স্পষ্ট। শেষ বাইট (নতুন লাইনের প্রতিনিধিত্ব করে) অপরিবর্তিত (সংখ্যা 10), কিন্তু অক্ষর "魚" একটি একক কোড "39770" এ রূপান্তরিত হয়েছে। একেই অক্ষর পড়া মানে! আপনি যদি বিশ্বাস না করেন যে 39770 "魚" অক্ষরটির প্রতিনিধিত্ব করে, তাহলে নিজেকে বোঝানো সহজ :)
import java.io.IOException;

public class Main {

   public static void main(String[] args) throws IOException {

       char x = 39770;
       System.out.println(x);
   }
}
কনসোল আউটপুট: কিন্তু যদি InputStreamReaderএত মহান হয়, কেন আমাদের প্রয়োজন BufferedReader? InputStreamReaderডাটা পড়তে এবং বাইটকে অক্ষরে রূপান্তর করতে জানে। আমরা আর কি চাইতে পারি? কেন অন্য পাঠক? :/ উত্তরটি খুবই সহজ: বৃহত্তর কর্মক্ষমতা এবং সুবিধার জন্য । পারফরম্যান্স দিয়ে শুরু করা যাক। ডেটা পড়ার সময় BufferedReader, এটি একটি বাফার নামে একটি বিশেষ এলাকা ব্যবহার করে, যেখানে এটি পড়া অক্ষরগুলিকে "সঞ্চয় করে"। শেষ পর্যন্ত, যখন এই অক্ষরগুলি প্রোগ্রামে প্রয়োজন হয়, তখন সেগুলি সরাসরি ডেটা উত্স (কীবোর্ড, ফাইল, ইত্যাদি) থেকে নয়, বাফার থেকে নেওয়া হবে। এটি অনেক সম্পদ সংরক্ষণ করে। এটি কীভাবে কাজ করে তা বোঝার জন্য, একটি বড় কোম্পানির একটি কুরিয়ার কল্পনা করুন। কুরিয়ার একটি অফিসে বসে আছে, কেউ ডেলিভারির জন্য প্যাকেজ নিয়ে আসার জন্য অপেক্ষা করছে। প্রতিবার যখন তিনি একটি নতুন প্যাকেজ পান, তিনি অবিলম্বে রাস্তায় আঘাত করতে পারেন। কিন্তু দিনের বেলা প্রচুর প্যাকেজ থাকতে পারে। তাকে অফিস এবং ডেলিভারির ঠিকানার মধ্যে প্রচুর ভ্রমণ করতে হবে। পরিবর্তে, কুরিয়ার তার অফিসে একটি বাক্স রাখে। প্রত্যেকে তাদের প্যাকেজগুলি বাক্সে রাখে। এখন কুরিয়ার শান্তভাবে বাক্সটি নিতে পারে এবং ঠিকানা থেকে ঠিকানায় যেতে পারে। এতে অনেক সময় বাঁচে, কারণ তাকে প্রতিবার অফিসে ফিরতে হয় না। এই উদাহরণে, বাক্সটি কেবল একটি বাফার, এবং অফিসটি একটি ডেটা উত্স৷ প্রতিবার অফিসে ফিরে যাওয়ার চেয়ে ডেলিভারি করার সময় একটি একক বাক্স থেকে প্যাকেজ নেওয়া কুরিয়ারের পক্ষে অনেক সহজ। সে পেট্রলও বাঁচাবে। একইভাবে, একটি প্রোগ্রামে প্রতিবার ডেটা উত্স উল্লেখ করার চেয়ে একটি বাফার থেকে ডেটা নেওয়ার জন্য এটি অনেক কম সম্পদ-নিবিড়। ফলে,BufferedReader+ একা InputStreamReaderথেকে দ্রুতInputStreamReader । আমরা কর্মক্ষমতা বিবেচনা করেছি. সুবিধার বিষয়ে কি? প্রধান সুবিধা হল যে Bufferedreaderডেটা একবারে শুধুমাত্র একটি অক্ষরই পড়তে পারে না (যদিও এটি তার পদ্ধতিতে এটি করতে পারে read()), তবে একই সময়ে পুরো লাইনও পড়তে পারে! এই readLine()পদ্ধতি ব্যবহার করে করা হয়;

public class Main {

   public static void main(String[] args) throws IOException {

       BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
       String s = reader.readLine();
       System.out.println("We read this line from the keyboard:");
       System.out.println(s);
   }
}
কনসোল আউটপুট: কোডজিম হল জাভা শেখার জন্য সেরা ওয়েবসাইট! আমরা কীবোর্ড থেকে এই লাইনটি পড়ি: কোডজিম হল জাভা শেখার জন্য সেরা ওয়েবসাইট! প্রচুর পরিমাণে ডেটা পড়ার সময় এটি বিশেষভাবে কার্যকর। অক্ষর অনুসারে পাঠ্য অক্ষরের এক বা দুই লাইন পড়া এখনও সম্ভব। কিন্তু "ওয়ার অ্যান্ড পিস" এ একবারে একটি চিঠি পড়া কিছুটা সমস্যাযুক্ত হবে :)
মন্তব্য
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION