পাইথনে `io` মডিউল

পাইথনে `io` মডিউল

এই প্রবন্ধে পাইথনের io মডিউল ব্যাখ্যা করা হয়েছে।

আমরা ব্যবহারিক উদাহরণের মাধ্যমে পাইথনের io মডিউল ব্যাখ্যা করব।

YouTube Video

পাইথনে io মডিউল

ইনপুট/আউটপুট প্রসেসিং ফাইল, নেটওয়ার্ক এবং স্ট্যান্ডার্ড I/O সহ সব ধরনের ডেটা কর্মের ভিত্তি গঠন করে। পাইথনের io মডিউল এই ইনপুট/আউটপুট অপারেশনগুলোকে একীভূত করার জন্য অ্যাবস্ট্রাক্ট ক্লাসের একটি সেট প্রদান করে। এই মডিউলটি বোঝার মূল ধারণা হচ্ছে "স্ট্রিম" এর ধারণা।

স্ট্রিম কী?

স্ট্রিম হল একটি বিমূর্ত প্রবাহ, যা ডেটা ধারাবাহিকভাবে ও ক্রমানুসারে পড়া ও লেখার জন্য ব্যবহৃত হয়।

ফাইলের বিষয়বস্তু বাইট বাইট করে পড়া বা নেটওয়ার্কের মাধ্যমে ডেটা পাঠানো ও গ্রহণ করার সময়, এগুলো সবই ডেটা স্ট্রিম হিসেবে পরিচালনা করা যায়।

এই কৌশলকে বিমূর্ত করে ফাইল, মেমরি ও নেটওয়ার্কের মতো বিভিন্ন I/O উৎসকে লেখার ও পড়ার মতো সাধারণ অপারেশনের মাধ্যমে পরিচালনা করা যায়।

পাইথনের io মডিউল স্ট্রিমের জন্য একটি একীভূত ইন্টারফেস দেয়, যার মাধ্যমে টেক্সট ও বাইনারি ডেটা দুইই দক্ষভাবে পরিচালনা করা যায়।

io মডিউলের মৌলিক গঠন

io মডিউল স্ট্রিমের প্রকৃতি অনুযায়ী তিন স্তরের একটি স্তরবিন্যাস রয়েছে।

  1. র’ স্তর (RawIOBase)

    RawIOBase সবচেয়ে নীচু স্তরের বাইট ইনপুট/আউটপুট পরিচালনা করে, যেমন OS ফাইল ডিসক্রিপ্টর ও ডিভাইস।

  2. বাফার্ড স্তর (BufferedIOBase)

    BufferedIOBase I/O কার্যকারিতা বাড়াতে একটি ক্যাশ (বাফার) প্রদান করে। BufferedReader এবং BufferedWriter এর সাধারণ উদাহরণ।

  3. টেক্সট স্তর (TextIOBase)

    TextIOBase বাইট সিকোয়েন্সকে স্ট্রিংয়ে রূপান্তর করে এবং এনকোডিং পরিচালনা করে। সাধারণত, open() ফাংশনের মাধ্যমে একটি ফাইল খোলা হলে এই স্তরের TextIOWrapper ব্যবহৃত হয়।

এই কাঠামোর কারণে io মডিউল টেক্সট এবং বাইনারি I/O কে পরিষ্কারভাবে আলাদা করে এবং একসাথে নমনীয়ভাবে ব্যবহার করার সুযোগ দেয়।

io মডিউলের মৌলিক গঠন

RawIOBase সবচেয়ে নীচের স্তরে OS ফাইল ডিসক্রিপ্টর পরিচালনা করে, তার ওপরে BufferedIOBase ক্যাশ যোগ করে, এবং শীর্ষ স্তরে TextIOBase স্ট্রিং রূপান্তর পরিচালনা করে।

1import io
2
3# Check the core base classes hierarchy
4print(io.IOBase.__subclasses__())
  • এই কোডটি IOBase থেকে উত্তরাধিকারসূত্রে প্রাপ্ত বিমূর্ত ক্লাসগুলোর গ্রুপ পরীক্ষা করার জন্য। TextIOBase, BufferedIOBase, এবং RawIOBase দেখতে পাবেন, যা স্তরবিন্যাসের নিশ্চিতকরণ।

io.IOBase: সকলের মূল ক্লাস

IOBase হল সব I/O অবজেক্টের বিমূর্ত মূল ক্লাস, যা close(), flush(), এবং seekable() এর মতো সাধারণ মেথড নির্ধারণ করে। একেবারে সরাসরি এর ব্যবহার বিরল; সাধারণত উত্তরাধিকারসূত্রে প্রাপ্ত ক্লাসের মাধ্যমে ব্যবহার করা হয়।

1import io
2
3f = io.StringIO("data")
4print(f.seekable())   # True
5print(f.readable())   # True
6print(f.writable())   # True
7f.close()
  • এই উদাহরণ দেখায়, IOBase-এর সাধারণ মেথডগুলো ওপরের স্তরের ক্লাসগুলোতেও ব্যবহৃত হতে পারে। seekable() এবং readable() কোনো স্ট্রিমের বৈশিষ্ট্য পরীক্ষা করতে সহায়ক।

io.RawIOBase: সবচেয়ে নীচু স্তর

RawIOBase হল OS ফাইল ডিসক্রিপ্টরের সবচেয়ে কাছের স্তর, এবং এটি কোনো বাফারিং করে না। সাধারণ ইমপ্লিমেন্টেশন হল FileIO, যা প্রতি বাইটে পড়া-লেখা করে।

1import io, os
2
3# Create a low-level FileIO object (no buffering)
4fd = os.open('raw_demo.bin', os.O_RDWR | os.O_CREAT)
5raw = io.FileIO(fd, mode='w+')
6raw.write(b'abc123')
7raw.seek(0)
8print(raw.read(6))  # b'abc123'
9raw.close()
  • FileIO হল RawIOBase-এর একটি বাস্তবায়ন; সকল পড়া ও লেখা bytes হিসেবে সম্পন্ন হয়। এটির সাথে উপরের স্তরের BufferedIOBase একত্রে ব্যবহার করলে দক্ষতা বাড়ানো যায়।

io.BufferedIOBase: মধ্যবর্তী স্তর (বাফারিং সহ)

BufferedIOBase একটি মধ্যবর্তী স্তর, যা বাফারিং করে ডিস্ক অ্যাক্সেস আরও দক্ষ করে তোলে। প্রধান বাস্তবায়নগুলি হচ্ছে BufferedReader, BufferedWriter, BufferedRandom, এবং BufferedRWPair

1import io
2
3# Create a buffered binary stream on top of a BytesIO (simulate file)
4base = io.BytesIO()
5buffered = io.BufferedWriter(base)
6buffered.write(b'Python IO buffering')
7buffered.flush()
8base.seek(0)
9print(base.read())  # b'Python IO buffering'
  • এই উদাহরণে, BufferedWriter-এর মাধ্যমে লেখা ডেটা কিছু সময়ের জন্য মেমরি বাফারে থাকে এবং flush() কল করলে নিচের স্তরে সেগুলো স্থানান্তরিত হয়।

BufferedReader-এর উদাহরণ

BufferedReader হল একটি শুধুমাত্র-পাঠযোগ্য বাফার করা স্ট্রিম, যা peek() এবং read() এর মাধ্যমে দক্ষ পঠনকে সমর্থন করে।

1import io
2
3stream = io.BytesIO(b"1234567890")
4reader = io.BufferedReader(stream)
5print(reader.peek(5))   # b'12345' (non-destructive)
6print(reader.read(4))   # b'1234'
7print(reader.read(3))   # b'567'
  • peek() শুধুমাত্র ডেটা "উঁকি দেয়", পয়েন্টার সরায় না। read()-এর সাথে এটি ব্যবহার করলে বাফারিং নমনীয়ভাবে নিয়ন্ত্রণ করতে পারেন।

io.TextIOBase: শুধুমাত্র টেক্সট স্তর

TextIOBase স্ট্রিং পরিচালনার জন্য একটি বিমূর্ত স্তর, যা অভ্যন্তরীণভাবে ডিকোডিং এবং এনকোডিং সম্পাদন করে। এক্ষেত্রে সাধারণ বাস্তবায়ন ক্লাস হল TextIOWrapper

 1import io
 2
 3# Wrap a binary stream to handle text encoding
 4binary = io.BytesIO()
 5text_stream = io.TextIOWrapper(binary, encoding='utf-8')
 6text_stream.write("\u3053\u3093\u306B\u3061\u306F")
 7text_stream.flush()
 8
 9# Reset stream position
10binary.seek(0)
11
12# Read bytes once
13data = binary.read()
14
15# Show both raw bytes and decoded text
16print("Raw bytes:", data)
17print("Decoded text:", data.decode('utf-8'))
  • এই উদাহরণে, TextIOWrapper স্ট্রিং কে UTF-8 এ এনকোড করে এবং আন্ডারলাইং বাইনারি স্ট্রিমে লেখে।

TextIOWrapper দিয়ে পড়ার উদাহরণ

পড়ার সময় স্বয়ংক্রিয়ভাবে ডিকোডিং করা হয়।

1import io
2
3binary_data = io.BytesIO("Python I/O".encode('utf-8'))
4text_reader = io.TextIOWrapper(binary_data, encoding='utf-8')
5print(text_reader.read())  # 'Python I/O'
  • TextIOWrapper টেক্সট I/O-র মৌলিক ক্লাস হিসেবে কাজ করে এবং প্রায় সকল উচ্চ স্তরের ফাইল অপারেশনের ভিত্তি গঠন করে।

io.StringIO: মেমরির ভিতরে টেক্সট স্ট্রিম

StringIO এমন একটি ক্লাস, যা মেমরিতে স্ট্রিংগুলোকে ফাইলের মতো পরিচালনা করতে দেয়। এটি I/O পরীক্ষার এবং অস্থায়ী ডেটা তৈরিতে উপকারী।

1import io
2
3text_buf = io.StringIO()
4text_buf.write("In-memory text stream")
5text_buf.seek(0)
6print(text_buf.read())  # 'In-memory text stream'
  • StringIO ডিস্ক ছাড়াই ফাইল সদৃশ অপারেশন করতে দেয় এবং ইউনিট টেস্টিং-এ ব্যাপকভাবে ব্যবহৃত হয়।

io.BytesIO: মেমরির ভিতরে বাইনারি স্ট্রিম

BytesIO হল একটি ইন-মেমরি ফাইল ক্লাস, যা বাইট সিকোয়েন্স (bytes) পরিচালনা করে। এটি বাইনারি প্রসেসিং বা ডেটা কম্প্রেশনের মত অবস্থার জন্য উপকারী, যেখানে ফাইল ব্যবহার করতে চান না।

1import io
2
3buf = io.BytesIO()
4buf.write(b'\x01\x02\x03')
5buf.seek(0)
6print(list(buf.read()))  # [1, 2, 3]
  • BytesIO-এর ইন্টারফেস BufferedIOBase-এর মতোই এবং এটি বহু ফাইল API-এর বিকল্প হিসেবে ব্যবহৃত হতে পারে।

কাস্টম স্ট্রিম (নিজস্ব ক্লাস তৈরি)

io-এর ক্লাসগুলো সম্প্রসারণযোগ্য, তাই আপনি নিজের স্ট্রিম ক্লাস তৈরি করতে পারেন। নিচে একটি TextIOBase সাবক্লাসের উদাহরণ দেওয়া হল, যা লেখার সময় সকল টেক্সটকে বড় অক্ষরে রূপান্তর করে।

 1import io
 2
 3class UpperTextIO(io.TextIOBase):
 4    def __init__(self):
 5        self.buffer = ""
 6    def write(self, s):
 7        self.buffer += s.upper()
 8        return len(s)
 9
10u = UpperTextIO()
11u.write("hello io")
12print(u.buffer)  # "HELLO IO"
  • TextIOBase-এর চুক্তি অনুসরণ করলে এই ধরনের যেকোনো কাস্টম আচরণ আপনি সংজ্ঞায়িত করতে পারেন। নির্দিষ্ট ব্যবহার যেমন ফাইল ও নেটওয়ার্কের জন্য স্ট্রিম বাড়ানোও সহজ।

সারসংক্ষেপ

io মডিউল ইনপুট/আউটপুট প্রসেসিংকে বিমূর্ত ও বাস্তব ক্লাসের স্তরে সাজিয়ে দেয়।

  • RawIOBase হল OS স্তরের বাইট I/O-র জন্য একটি ক্লাস।
  • BufferedIOBase সেই ক্লাস, যা দক্ষ ক্যাশ স্তর প্রদান করে।
  • TextIOBase হল এমন এক ক্লাস, যা স্ট্রিং পড়া ও লেখা পরিচালনা করে।
  • StringIOBytesIO হল মেমরির ভিতরে স্ট্রিমের ক্লাস।

এই ক্লাসগুলো বোঝার মাধ্যমে আপনি পাইথনের I/O সিস্টেমের কার্যপ্রণালী সঠিকভাবে অনুধাবন করতে ও তা ফাইল কার্যক্রম, নেটওয়ার্ক যোগাযোগ এবং টেস্ট স্ট্রিমের ডিজাইনে প্রয়োগ করতে পারবেন।

আপনি আমাদের ইউটিউব চ্যানেলে ভিজ্যুয়াল স্টুডিও কোড ব্যবহার করে উপরের নিবন্ধটি অনুসরণ করতে পারেন। দয়া করে ইউটিউব চ্যানেলটিও দেখুন।

YouTube Video