"হাই, অ্যামিগো!"

"হাই, বিলাবো! জীবন কেমন চলছে?"

"দারুণ। গতকাল, আমি কিছু পরজীবী থেকে পরিত্রাণ পাওয়ার চেষ্টা করেছি, কিন্তু এখনও পর্যন্ত আমি খুব বেশি সফলতা পাইনি। এবং তারপরে আমাকে আবার আবর্জনার মধ্যে রাত কাটাতে হয়েছিল।"

"তাহলে... সবকিছু কি এখনও দুর্দান্ত?"

"তুমি এটা বলতে পারতে."

"ভালো। তাহলে আজ আমার জন্য তোমার কি আছে?"

"আজ আমি আপনাকে RandomAccessFile ক্লাস সম্পর্কে বলব ।"

RandomAccessFile, ইত্যাদি - 1

"বিষয়টি হল, FileInputStream এবং FileOutputStream ফাইলগুলিকে স্ট্রীম হিসাবে উপস্থাপন করে: আপনি কেবলমাত্র তাদের ক্রমানুসারে পড়তে এবং লিখতে পারেন।"

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

" এই সমস্যাটি সমাধান করার জন্য RandomAccessFile ক্লাস তৈরি করা হয়েছে। আপনি ফাইলের যেকোনো জায়গায় লিখতে, এটি থেকে পড়তে, সেইসাথে একই সময়ে ফাইলটি পড়তে এবং লিখতে এটি ব্যবহার করতে পারেন।"

"কি চমৎকার!"

"হ্যাঁ। এটা আসলে বেশ সুবিধাজনক।"

"কিন্তু আপনি কিভাবে একটি নির্বিচারে অবস্থান থেকে পড়া?"

"এটি সবই বেশ সহজ। কল্পনা করুন যে আপনার কাছে একটি টেক্সট এডিটর আছে, যেমন নোটপ্যাড, খোলা আছে। এতে একটি কার্সার রয়েছে। আপনি যখন কিছু টাইপ করেন, তখন কার্সার যেখানেই থাকে সেখানে পাঠ্য যোগ করা হয়। একটি ফাইল পড়া একই। থেকে পড়া শুরু হয় 'কারসার' যেখানেই থাকুক না কেন। পড়ার/লেখার সময়, কার্সার স্বয়ংক্রিয়ভাবে চলে যায়।"

"এখানে, আপনাকে একটি উদাহরণ দেখানো ভাল হবে:"

একটি ফাইল পড়া:
// r - read, the file is opened only for reading.
RandomAccessFile raf = new RandomAccessFile("input.txt", "r");

// Move the «cursor» to the 100th character.
raf.seek(100);

// Read the line starting from the current cursor position until the end of the line.
String text = raf.readLine();

// Close the file.
raf.close();

"এই উদাহরণে, আমি দুটি জিনিসের প্রতি আপনার দৃষ্টি আকর্ষণ করতে চাই:"

"প্রথম, RandomAccessFile অবজেক্টের সৃষ্টি । দ্বিতীয় যুক্তিটি হল r অক্ষর। এর মানে হল যে ফাইলটি পড়ার জন্য খোলা হয়েছে ( r - পড়া )। আপনি যদি পড়া এবং লেখার জন্য একটি ফাইল খুলতে চান তবে আপনাকে « rw পাস করতে হবে » কনস্ট্রাক্টরের কাছে, শুধু « r » এর পরিবর্তে।

"দ্বিতীয়, সন্ধানের পদ্ধতিটি দেখুন। আপনি এই পদ্ধতিটি ব্যবহার করে ফাইলের চারপাশে লাফ দিতে এবং বর্তমান পঠন/লেখার ক্রিয়াকলাপের জন্য কার্সারের অবস্থান পরিবর্তন করতে পারেন। যখন একটি ফাইল প্রথম খোলা হয়, তখন কার্সারটি 0ম বাইটে সেট করা হয়। অথবা, আরো সঠিকভাবে, জিরোথ বাইটের আগে।"

"আমি কি সঠিকভাবে বুঝতে পেরেছি? আমরা ফাইলটি খুলি, এবং কার্সারটি একেবারে শুরুতে - অবস্থান 0-এ। তারপরে আমরা সন্ধান করি এবং কার্সারটিকে 100 তম বাইটে নিয়ে যাই। এবং যখন আমরা readLine কল করি , এটি শততম বাইট থেকে পড়া শুরু করে ঠিক?

"হ্যাঁ। কিন্তু আমি আপনার দৃষ্টি আকর্ষণ করতে চাই যে অনুসন্ধান পদ্ধতি আপনাকে ফাইলের চারপাশে নির্বিচারে লাফ দিতে দেয়। উদাহরণস্বরূপ:"

একটি ফাইল পড়া:
// r - read, the file is opened only for reading.
RandomAccessFile raf = new RandomAccessFile("input.txt", "r");

// The "cursor" is at the 0th character.
String text1 = raf.readLine();

// Move the "cursor" to the 100th character.
raf.seek(100);
String text2 = raf.readLine();

// Move the "cursor" to the 0th character.
raf.seek(0);
String text3 = raf.readLine();

// Close the file
raf.close();

"এই উদাহরণে, আমরা প্রথমে 0 তম বাইট থেকে শুরু হওয়া একটি লাইন পড়ি। তারপরে আমরা শততম বাইটে ঝাঁপিয়ে পড়ি এবং সেখানে একটি লাইন পড়ি। তারপরে আমরা আবার 0 তম বাইটে গিয়ে একটি লাইন পড়ি। এর মানে হল যে text1 এবং text3 অভিন্ন স্ট্রিং।"

"আহ. এটা জিনিস পরিষ্কার করে তোলে।"

"দারুণ। তারপর এখানে আরেকটি উদাহরণ:"

একটি ফাইল পড়া:
// rw - read/write, the file is opened for reading and writing.
RandomAccessFile raf = new RandomAccessFile("seek.txt", "rw");

// Write to the file, starting from the 0th byte.
raf.writeBytes("It is a string");

// Move the "cursor" to the 8th character.
raf.seek(8);

// Write "surprise!" to the file.
raf.writeBytes("surprise!");

// Close the file.
raf.close();

"এখানে আমরা কনস্ট্রাক্টরের কাছে « rw » ( read/write ) পাস করে পড়ার এবং লেখার জন্য ফাইলটি খুলি ।"

তারপরে আমরা ফাইলটিতে লিখি « এটি একটি স্ট্রিং »।

"তারপর আমরা কার্সারটিকে 8 তম বাইটে নিয়ে যাই (যা 'স্ট্রিং' শব্দের শুরুতে হয়)"

"তারপর আমরা লিখি « আশ্চর্য !»"

"ফলে, ফাইলটিতে রয়েছে « এটি একটি আশ্চর্য !»"

"তাহলে, বাইটগুলি ফাইলের মাঝখানে ঢোকানো হয় না, বরং তারা সেখানে থাকাগুলিকে প্রতিস্থাপন করে?"

"হ্যাঁ।"

"যদি আমরা কার্সারটিকে ফাইলের একেবারে শেষে নিয়ে যাই?"

"তাহলে বাইটগুলি শেষ পর্যন্ত লেখা হবে, এবং ফাইলটি আরও বড় হবে। সুতরাং এটি প্রায় পাঠ্য সম্পাদকে পাঠ্য লেখার মতো হবে।"

"হুম। আমি মনে করি আমি সবকিছু বুঝতে পেরেছি। আপনি কি RandomAccessFile ক্লাসের পদ্ধতিগুলির একটি সম্পূর্ণ তালিকা দিতে পারেন?"

"আপনি যেতে এখানে নিশ্চিত:"

পদ্ধতি বর্ণনা
int read() এক বাইট পড়ে এবং ফেরত দেয়
int read(byte b[], int off, int len) বাইটের একটি অ্যারে পড়ে
int read(byte b[]) বাইটের একটি অ্যারে পড়ে
void readFully(byte b[]) বাইটের একটি অ্যারে পড়ে, এবং অ্যারে পূরণ করার জন্য যথেষ্ট না থাকলে নতুন বাইট যোগ করার জন্য অপেক্ষা করে
int skipBytes(int n) n বাইট এড়িয়ে যান। অন্য কথায়, এটি কার্সারকে এন বাইট এগিয়ে নিয়ে যায়।
void write(int b) কার্সারের অবস্থানে এক বাইট লেখে
void write(byte b[]) কার্সারের অবস্থানে বাইটের একটি অ্যারে লেখে
void write(byte b[], int off, int len) কার্সারের অবস্থানে বাইটের একটি অ্যারে লেখে
long getFilePointer() কার্সার যে বাইটের দিকে নির্দেশ করছে তার সংখ্যা প্রদান করে। এটি 0 থেকে ফাইলের দৈর্ঘ্য পর্যন্ত হতে পারে
void seek(long pos) পড়া/লেখার জন্য ব্যবহৃত «কারসার» নির্দিষ্ট স্থানে নিয়ে যায়
long length() ফাইলের দৈর্ঘ্য ফেরত দেয়
void setLength(long newLength) একটি নতুন ফাইলের দৈর্ঘ্য সেট করে। ফাইলটি বড় হলে, এটি কেটে ফেলা হয়; যদি এটি ছোট হয়, তাহলে এটি ফাইলটি প্রসারিত করে এবং শূন্য দিয়ে নতুন স্থান পূরণ করে
void close() ফাইল বন্ধ করে দেয়
boolean readBoolean() ফাইলে কার্সারের বর্তমান অবস্থান থেকে একটি বুলিয়ান পড়ে
byte readByte() ফাইলে কার্সারের বর্তমান অবস্থান থেকে একটি বাইট পড়ে
char readChar() ফাইলে কার্সারের বর্তমান অবস্থান থেকে একটি অক্ষর পড়ে
int readInt() ফাইলে কার্সারের বর্তমান অবস্থান থেকে একটি int পড়ে
long readLong() ফাইলে কার্সারের বর্তমান অবস্থান থেকে একটি দীর্ঘ পড়ে
float readFloat() ফাইলে কার্সারের বর্তমান অবস্থান থেকে একটি ফ্লোট পড়ে
double readDouble() ফাইলে কার্সারের বর্তমান অবস্থান থেকে একটি ডবল পড়ে
String readLine() ফাইল থেকে একটি লাইন পড়ে এবং এটি ফেরত দেয়
void writeBoolean(boolean v) ফাইলে একটি বুলিয়ান লেখে (কারসারের অবস্থান থেকে শুরু করে)
void writeByte(int v) t ফাইলে একটি বাইট লেখে (কারসরের অবস্থান থেকে শুরু করে)
void writeChar(int v) ফাইলে একটি অক্ষর লেখে (কারসরের অবস্থান থেকে শুরু করে)
void writeInt(int v) ফাইলে একটি int লিখে (কারসারের অবস্থান থেকে শুরু করে)
void writeLong(long v) ফাইলে লম্বা লেখে (কারসারের অবস্থান থেকে শুরু করে)
void writeFloat(float v) ফাইলে একটি ফ্লোট লেখে (কারসরের অবস্থান থেকে শুরু করে)
void writeDouble(double v) ফাইলে একটি ডবল লেখে (কারসরের অবস্থান থেকে শুরু করে)
void writeBytes(String s) ফাইলে একটি স্ট্রিং লেখে (কারসরের অবস্থান থেকে শুরু করে)
void writeChars(String s) ফাইলে একটি স্ট্রিং লেখে (কারসরের অবস্থান থেকে শুরু করে)

"হুম। তাই, এখানে নতুন কিছু নেই। সম্ভবত seek()/getFilePointer() এবং length()/setLength() পদ্ধতি জোড়া ছাড়া।"

"হ্যাঁ, অ্যামিগো। সবকিছু একই রকম। কিন্তু এটা কি সুবিধাজনক নয়?"

"এটা সুবিধাজনক। আপনাকে ধন্যবাদ, বিলাবো, একটি আকর্ষণীয় পাঠের জন্য এবং আপনি আমাকে যে উদাহরণ দিয়েছেন তার জন্য।"

"সাহায্য করতে পেরে আনন্দিত, আমিগো, আমার বন্ধু!"