1. ডেটা স্ট্রিম

খুব কমই একটি প্রোগ্রাম নিজের কাছে একটি দ্বীপ হিসাবে বিদ্যমান। প্রোগ্রামগুলি সাধারণত কোনও না কোনওভাবে "বাইরের বিশ্বের" সাথে যোগাযোগ করে। এটি কীবোর্ড থেকে ডেটা পড়ার মাধ্যমে, বার্তা পাঠানোর মাধ্যমে, ইন্টারনেট থেকে পৃষ্ঠাগুলি ডাউনলোড করার মাধ্যমে বা বিপরীতভাবে, একটি দূরবর্তী সার্ভারে ফাইল আপলোড করার মাধ্যমে ঘটতে পারে।

আমরা এক কথায় এই সমস্ত আচরণের উল্লেখ করতে পারি: প্রোগ্রাম এবং বাইরের বিশ্বের মধ্যে ডেটা বিনিময় । অপেক্ষা করুন, এটি শুধু একটি শব্দ নয়।

অবশ্যই, ডেটা বিনিময় নিজেই দুটি অংশে বিভক্ত করা যেতে পারে: ডেটা গ্রহণ করা এবং ডেটা পাঠানো। উদাহরণস্বরূপ, আপনি একটি Scannerবস্তু ব্যবহার করে কীবোর্ড থেকে ডেটা পড়েন — এটি ডেটা গ্রহণ করছে। এবং আপনি একটি কমান্ড ব্যবহার করে স্ক্রিনে ডেটা প্রদর্শন করেন System.out.println()- এটি ডেটা পাঠাচ্ছে।

প্রোগ্রামিং-এ, "স্ট্রীম" শব্দটি ডেটা বিনিময়কে বর্ণনা করতে ব্যবহৃত হয়। যে শব্দ কোথা থেকে এসেছে?

বাস্তব জীবনে, আপনি জলের স্রোত বা চেতনার স্রোত থাকতে পারেন। প্রোগ্রামিং এ, আমাদের ডেটা স্ট্রিম আছে ।

স্ট্রিম একটি বহুমুখী হাতিয়ার. তারা প্রোগ্রামটিকে যেকোন জায়গা (ইনপুট স্ট্রীম) থেকে ডেটা গ্রহণ করতে এবং যে কোনও জায়গায় (আউটপুট স্ট্রীম) ডেটা প্রেরণের অনুমতি দেয়। সুতরাং, দুটি ধরনের আছে:

  • একটি ইনপুট স্ট্রীম ডেটা গ্রহণের জন্য
  • একটি আউটপুট স্ট্রিম ডেটা পাঠানোর জন্য

স্ট্রিমগুলিকে 'ট্যাঞ্জিবল' করার জন্য, জাভার নির্মাতারা দুটি শ্রেণী লিখেছেন: InputStreamএবং OutputStream.

ক্লাসের InputStreamএকটি read()পদ্ধতি রয়েছে যা আপনাকে এটি থেকে ডেটা পড়তে দেয়। এবং OutputStreamক্লাসের একটি write()পদ্ধতি রয়েছে যা আপনাকে এটিতে ডেটা লিখতে দেয়। তাদের অন্যান্য পদ্ধতিও রয়েছে, তবে পরে আরও বেশি।

বাইট স্ট্রীম

আমরা কি ধরনের তথ্য সম্পর্কে কথা বলছি? এটা কি বিন্যাস লাগে? অন্য কথায়, এই ক্লাসগুলি কি ধরনের ডেটা সমর্থন করে?

এগুলি জেনেরিক ক্লাস, তাই তারা সর্বাধিক সাধারণ ডেটা টাইপকে সমর্থন করে — byte. একটি OutputStreamবাইট (এবং বাইট অ্যারে) লিখতে পারে এবং একটি InputStreamবস্তু বাইট (বা বাইট অ্যারে) পড়তে পারে। এটিই - তারা অন্য কোনও ডেটা প্রকার সমর্থন করে না।

ফলস্বরূপ, এই প্রবাহগুলিকে বাইট স্ট্রীমও বলা হয় ।

স্ট্রিমগুলির একটি বৈশিষ্ট্য হ'ল তাদের ডেটা কেবল ক্রমিকভাবে পড়া (বা লিখিত) হতে পারে। আপনি একটি স্ট্রিমের মাঝখানে থেকে এর আগে আসা সমস্ত ডেটা না পড়ে ডেটা পড়তে পারবেন না৷

এইভাবে কীবোর্ড থেকে ডেটা পড়া Scannerক্লাসের মাধ্যমে কাজ করে: আপনি কীবোর্ড থেকে ক্রমিকভাবে, লাইনে লাইনে ডেটা পড়েন। আমরা একটি লাইন, তারপর পরের লাইন, তারপর পরের লাইন, এবং তাই পড়া. উপযুক্তভাবে, লাইন পড়ার পদ্ধতি বলা হয় nextLine()

একটিতে ডেটা লেখাও OutputStreamক্রমানুসারে ঘটে। এর একটি ভাল উদাহরণ হল কনসোল আউটপুট। আপনি একটি লাইন আউটপুট, আরেকটি এবং অন্য দ্বারা অনুসরণ. এটি ক্রমিক আউটপুট। আপনি প্রথম লাইন, তারপর দশম এবং তারপর দ্বিতীয়টি আউটপুট করতে পারবেন না। সমস্ত ডেটা আউটপুট স্ট্রীমে শুধুমাত্র ক্রমানুসারে লেখা হয়।

চরিত্রের ধারা

আপনি সম্প্রতি শিখেছেন যে স্ট্রিং হল দ্বিতীয় জনপ্রিয় ডেটা টাইপ, এবং প্রকৃতপক্ষে সেগুলি। অনেক তথ্য অক্ষর এবং পুরো স্ট্রিং আকারে চারপাশে পাস করা হয়. একটি কম্পিউটার বাইট হিসাবে সবকিছু পাঠাতে এবং গ্রহণ করতে পারদর্শী, কিন্তু মানুষ ততটা নিখুঁত নয়।

এই সত্যের জন্য অ্যাকাউন্টিং, জাভা প্রোগ্রামাররা আরও দুটি ক্লাস লিখেছেন: Readerএবং Writer. ক্লাসটি ক্লাসের Readerসাথে সাদৃশ্যপূর্ণ InputStream, তবে এর read()পদ্ধতি বাইট নয়, অক্ষর ( char) পড়ে। ক্লাস ক্লাসের Writerসাথে মিলে যায় OutputStream। এবং ক্লাসের মতই Reader, এটি অক্ষর ( char) দিয়ে কাজ করে, বাইট নয়।

যদি আমরা এই চারটি শ্রেণীর তুলনা করি, আমরা নিম্নলিখিত চিত্রটি পাই:

বাইট (বাইট) অক্ষর (চর)
ডেটা পড়া
InputStream
Reader
ডেটা লেখা
OutputStream
Writer

ব্যবহারিক প্রয়োগ

, , এবং শ্রেণীগুলি নিজেরাই সরাসরি কেউ ব্যবহার করে না, যেহেতু তারা এমন কোনও কংক্রিট বস্তুর সাথে যুক্ত নয় যেখান থেকে ডেটা পড়া যায় (বা যেগুলিতে ডেটা লেখা যেতে পারে) InputStream। কিন্তু এই চারটি শ্রেণীতে প্রচুর বংশধর শ্রেণী রয়েছে যা অনেক কিছু করতে পারে।OutputStreamReaderWriter


2. InputStreamক্লাস

ক্লাসটি InputStreamআকর্ষণীয় কারণ এটি শত শত বংশধর শ্রেণীর জন্য অভিভাবক শ্রেণী। এটির নিজস্ব কোনো ডেটা নেই, তবে এটির এমন পদ্ধতি রয়েছে যা এর সমস্ত প্রাপ্ত ক্লাস উত্তরাধিকারসূত্রে পায়।

সাধারণভাবে, স্ট্রিম অবজেক্টের জন্য অভ্যন্তরীণভাবে ডেটা সঞ্চয় করা বিরল। একটি স্ট্রিম ডেটা পড়ার/লেখার জন্য একটি টুল, কিন্তু স্টোরেজ নয়। যে বলেন, ব্যতিক্রম আছে.

ক্লাসের পদ্ধতি InputStreamএবং এর সমস্ত বংশধর শ্রেণীর:

পদ্ধতি বর্ণনা
int read()
স্ট্রীম থেকে এক বাইট পড়ে
int read(byte[] buffer)
স্ট্রীম থেকে বাইটের একটি অ্যারে পড়ে
byte[] readAllBytes()
স্ট্রীম থেকে সমস্ত বাইট পড়ে
long skip(long n)
nস্ট্রীমে বাইটগুলি এড়িয়ে যায় (এগুলি পড়ে এবং বাতিল করে)
int available()
প্রবাহে কত বাইট বাকি আছে তা পরীক্ষা করে
void close()
স্রোত বন্ধ করে দেয়

আসুন সংক্ষিপ্তভাবে এই পদ্ধতিগুলির মধ্য দিয়ে যাওয়া যাক:

read()পদ্ধতি

পদ্ধতিটি স্ট্রীম থেকে একটি বাইটread() পড়ে এবং এটি ফেরত দেয়। আপনি রিটার্ন টাইপ দ্বারা বিভ্রান্ত হতে পারে . এই প্রকারটি বেছে নেওয়া হয়েছে কারণ এটি আদর্শ পূর্ণসংখ্যার প্রকার। প্রথম তিনটি বাইট শূন্য হবে।intintint

read(byte[] buffer)পদ্ধতি

এটি পদ্ধতির দ্বিতীয় রূপ read()InputStreamএটি আপনাকে একবারে একটি থেকে একটি বাইট অ্যারে পড়তে দেয় । অ্যারে যে বাইট সংরক্ষণ করবে একটি যুক্তি হিসাবে পাস করা আবশ্যক. পদ্ধতিটি একটি সংখ্যা প্রদান করে - প্রকৃতপক্ষে পড়া বাইটের সংখ্যা।

ধরা যাক আপনার একটি 10 ​​কিলোবাইট বাফার আছে এবং আপনি FileInputStreamক্লাস ব্যবহার করে একটি ফাইল থেকে ডেটা পড়ছেন। যদি ফাইলটিতে শুধুমাত্র 2 কিলোবাইট থাকে, তবে সমস্ত ডেটা বাফার অ্যারেতে লোড হবে এবং পদ্ধতিটি 2048 নম্বর (2 কিলোবাইট) প্রদান করবে।

readAllBytes()পদ্ধতি

একটি খুব ভাল পদ্ধতি. InputStreamএটি ফুরিয়ে যাওয়া পর্যন্ত সমস্ত ডেটা পড়ে এবং এটি একটি একক বাইট অ্যারে হিসাবে ফেরত দেয়। ছোট ফাইল পড়ার জন্য এটি খুব সহজ। বড় ফাইলগুলি শারীরিকভাবে মেমরিতে ফিট নাও হতে পারে এবং পদ্ধতিটি একটি ব্যতিক্রম নিক্ষেপ করবে।

skip(long n)পদ্ধতি

এই পদ্ধতিটি আপনাকে অবজেক্ট থেকে প্রথম n বাইটগুলি এড়িয়ে যেতে দেয় InputStream। যেহেতু ডেটা কঠোরভাবে ক্রমানুসারে পড়া হয়, এই পদ্ধতিটি কেবল স্ট্রিম থেকে প্রথম n বাইটগুলি পড়ে এবং সেগুলি বাতিল করে।

প্রকৃতপক্ষে এড়িয়ে যাওয়া বাইটগুলির সংখ্যা প্রদান করে (যদি nবাইটগুলি এড়িয়ে যাওয়ার আগে স্ট্রিমটি শেষ হয়ে যায়)।

int available()পদ্ধতি

পদ্ধতিটি স্ট্রীমে এখনও অবশিষ্ট বাইটের সংখ্যা প্রদান করে

void close()পদ্ধতি

পদ্ধতিটি close()ডেটা স্ট্রীম বন্ধ করে এবং এর সাথে যুক্ত বাহ্যিক সংস্থানগুলি প্রকাশ করে। একবার একটি স্ট্রিম বন্ধ হয়ে গেলে, এটি থেকে আর কোনও ডেটা পড়া যাবে না।

আসুন একটি উদাহরণ প্রোগ্রাম লিখি যা একটি খুব বড় ফাইল কপি করে। আমরা readAllBytes()মেমরিতে সম্পূর্ণ ফাইল পড়ার পদ্ধতি ব্যবহার করতে পারি না। উদাহরণ:

কোড বিঃদ্রঃ
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileInputStream input = new FileInputStream(src);
FileOutputStream output = new FileOutputStream(dest))
{
   byte[] buffer = new byte[65536]; // 64Kb
   while (input.available() > 0)
   {
      int real = input.read(buffer);
      output.write(buffer, 0, real);
   }
}



InputStreamফাইল থেকে পড়ার জন্য
OutputStreamলিখুন ফাইল

বাফারের জন্য যেটিতে আমরা ডেটা পড়ব
যতক্ষণ স্ট্রীমে ডেটা থাকে ততক্ষণ

বাফারে ডেটা পড়ুন
বাফার থেকে দ্বিতীয় স্ট্রীমে ডেটা লিখুন

এই উদাহরণে, আমরা দুটি শ্রেণী ব্যবহার করেছি: একটি ফাইল থেকে ডেটা পড়ার জন্য FileInputStreamএকটি বংশধর InputStreamএবং একটি ফাইলে ডেটা লেখার জন্য FileOutputStreamএকটি বংশধর ৷ OutputStreamআমরা একটু পরে দ্বিতীয় শ্রেণীর কথা বলব।

এখানে আরেকটি আকর্ষণীয় পয়েন্ট হল realপরিবর্তনশীল। যখন একটি ফাইল থেকে ডেটার শেষ ব্লকটি পড়া হয়, তখন এতে সহজেই 64KB এর কম ডেটা থাকতে পারে। তদনুসারে, আমাদের সম্পূর্ণ বাফার নয়, তবে এটির শুধুমাত্র একটি অংশ - প্রথম realবাইটগুলি আউটপুট করতে হবে। এই পদ্ধতিতে ঠিক কি হয় write()



3. Readerক্লাস

ক্লাসটি Readerক্লাসের একটি সম্পূর্ণ অ্যানালগ InputStream। শুধুমাত্র একটি পার্থক্য হল এটি অক্ষরের সাথে কাজ করে ( char), বাইট দিয়ে নয়। ক্লাসের মতই InputStream, Readerশ্রেণীটি নিজে থেকে কোথাও ব্যবহৃত হয় না: এটি শত শত বংশধর শ্রেণীর জন্য অভিভাবক শ্রেণী এবং তাদের সকলের জন্য সাধারণ পদ্ধতি সংজ্ঞায়িত করে।

ক্লাসের পদ্ধতি Reader(এবং এর সমস্ত বংশধর শ্রেণী):

পদ্ধতি বর্ণনা
int read()
charস্রোত থেকে একটি পড়ে
int read(char[] buffer)
charস্ট্রীম থেকে একটি অ্যারে পড়ে
long skip(long n)
n charsস্ট্রীমে এড়িয়ে যায় (এগুলি পড়ে এবং বাতিল করে)
boolean ready()
প্রবাহে এখনও কিছু অবশিষ্ট আছে কিনা তা পরীক্ষা করে
void close()
স্রোত বন্ধ করে দেয়

পদ্ধতিগুলি ক্লাসের সাথে খুব মিল InputStream, যদিও সামান্য পার্থক্য রয়েছে।

int read()পদ্ধতি

এই পদ্ধতিটি charস্ট্রিম থেকে একটি পড়ে এবং এটি ফেরত দেয়। টাইপ charএকটি তে প্রসারিত হয় int, কিন্তু ফলাফলের প্রথম দুটি বাইট সবসময় শূন্য থাকে।

int read(char[] buffer)পদ্ধতি

এটি পদ্ধতির দ্বিতীয় রূপ read()Readerএটি আপনাকে একবারে একটি থেকে একটি চার অ্যারে পড়তে দেয় । যে অ্যারে অক্ষর সংরক্ষণ করবে একটি যুক্তি হিসাবে পাস করা আবশ্যক. পদ্ধতিটি একটি সংখ্যা প্রদান করে — প্রকৃতপক্ষে পড়া অক্ষরের সংখ্যা।

skip(long n)পদ্ধতি

এই পদ্ধতিটি আপনাকে অবজেক্ট থেকে প্রথম n অক্ষরগুলি এড়িয়ে যেতে দেয় Reader। এটি ক্লাসের সাদৃশ্য পদ্ধতির মতোই কাজ করে InputStream। আসলে এড়িয়ে যাওয়া অক্ষরের সংখ্যা দেখায়।

boolean ready()পদ্ধতি

trueপ্রবাহে অপঠিত বাইট থাকলে রিটার্ন করে ।

void close()পদ্ধতি

পদ্ধতিটি close()ডেটা স্ট্রীম বন্ধ করে এবং এর সাথে যুক্ত বাহ্যিক সংস্থানগুলি প্রকাশ করে। একবার একটি স্ট্রিম বন্ধ হয়ে গেলে, এটি থেকে আর কোনও ডেটা পড়া যাবে না।

তুলনা করার জন্য, আসুন একটি প্রোগ্রাম লিখি যা একটি পাঠ্য ফাইল অনুলিপি করে:

কোড বিঃদ্রঃ
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileReader reader = new FileReader(src);
FileWriter writer = new FileWriter(dest))
{
   char[] buffer = new char[65536]; // 128Kb
   while (reader.ready())
   {
      int real = reader.read(buffer);
      writer.write(buffer, 0, real);
   }
}



Readerএকটি ফাইল থেকে পড়ার জন্য
Writerএকটি ফাইলে লেখার জন্য

বাফার যেখানে আমরা ডেটা পড়ব
যতক্ষণ স্ট্রীমে ডেটা থাকে ততক্ষণ

একটি বাফারে ডেটা পড়ুন
বাফার থেকে দ্বিতীয় স্ট্রীমে ডেটা লিখুন