ফাইল পড়া ও লেখা
এই পাঠে যা শিখবেন
- Text ফাইল পড়া ও লেখা —
open()ও context manager - Mode ও encoding — কখন কোনটা
- CSV ফাইল —
csvmodule-এ পড়া - JSON ফাইল — Python dict ↔ disk
- pathlib — modern path management
- AI dataset (CSV, JSON, JSONL) load করার pattern
১ · Text ফাইল লেখা ও পড়া
File I/O — disk-এর সাথে কথোপকথন। Python-এ আদর্শ pattern: context managerContext Manager"with" statement-এর সাথে ব্যবহৃত object — ব্লক শেষে cleanup auto। file close, lock release — সাধারণ ব্যবহার। __enter__, __exit__ dunder methods। (with) — auto-close।
# লেখা
with open("hello.txt", "w", encoding="utf-8") as f:
f.write("নমস্কার, পাইথন!\n")
f.write("দ্বিতীয় লাইন\n")
f.write("তৃতীয় লাইন\n")
# পুরো পড়া
with open("hello.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)
# লাইন-বাই-লাইন
print("--- লাইন আকারে ---")
with open("hello.txt", "r", encoding="utf-8") as f:
for i, line in enumerate(f, 1):
print(f"{i}: {line.rstrip()}")
with block শেষে file auto-close — এমনকি error হলেও। বিনা with — file leak, OS-এ resource ফাঁক। সবসময় with ব্যবহার করুন।
২ · Mode-এর সংক্ষেপ
"r" — read (default)। ফাইল না থাকলে error।
"w" — write। ফাইল থাকলে overwrite!
"a" — append। শেষে যোগ।
"x" — exclusive create। থাকলে error।
"b" — binary mode (image, audio, model weights)।
"r+"/"w+" — read+write।
"w" mode — পুরনো content চিরতরে মুছে দেয়। গুরুত্বপূর্ণ ফাইলে "x" ব্যবহার করুন (থাকলে error দেবে, accidental overwrite থেকে বাঁচায়)।
৩ · Encoding — Bangla-র জন্য বিশেষ গুরুত্ব
Computer-এ সব text বাইটে রাখা — কিন্তু কোন বাইট কোন অক্ষর? — encodingEncodingঅক্ষর ↔ বাইটের mapping। ASCII (১২৮ char), Latin-1 (২৫৬), UTF-8 (১,১১,০০০+ char — সব ভাষা)। আজকের default UTF-8।।
# Bangla লেখা — অবশ্যই UTF-8
text = "বাংলা টেক্সট: কেমন আছেন?"
with open("bangla.txt", "w", encoding="utf-8") as f:
f.write(text)
# UTF-8-এ পড়া — ঠিক
with open("bangla.txt", "r", encoding="utf-8") as f:
print(f.read())
# Bytes — internal representation
with open("bangla.txt", "rb") as f:
raw = f.read()
print(f"মোট bytes: {len(raw)}")
print(f"প্রথম ১০: {raw[:10]}")
cp1252 (Latin-1)। Bangla-তে garbled text। সবসময় encoding="utf-8" explicitly দিন।
৪ · CSV ফাইল — table data
import csv
# লেখা
rows = [
["name", "age", "score"],
["রহিম", 22, 85],
["ফাতেমা", 21, 92],
["করিম", 23, 78],
]
with open("students.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
writer.writerows(rows)
# পড়া
print("--- csv.reader ---")
with open("students.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f)
for row in reader:
print(row)
# DictReader — header → key
print("\n--- DictReader ---")
with open("students.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
print(f"{row['name']} → {row['score']}")
csv module-এর উপর। L13 থেকে আমরা Pandas দেখব।
৫ · JSON ফাইল — structured data
import json
# Python dict → JSON file
config = {
"model": "BERT-base",
"hyperparameters": {
"lr": 0.0001,
"batch_size": 32,
"epochs": 10
},
"languages": ["bangla", "english"]
}
with open("config.json", "w", encoding="utf-8") as f:
json.dump(config, f, indent=2, ensure_ascii=False)
# JSON file → Python dict
with open("config.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
print(loaded)
print(f"Learning rate: {loaded['hyperparameters']['lr']}")
# JSONL — প্রতি লাইনে একটি JSON object (AI dataset standard)
records = [
{"id": 1, "text": "প্রথম sentence"},
{"id": 2, "text": "দ্বিতীয় sentence"},
{"id": 3, "text": "তৃতীয় sentence"},
]
with open("data.jsonl", "w", encoding="utf-8") as f:
for rec in records:
f.write(json.dumps(rec, ensure_ascii=False) + "\n")
# পড়া — generator
print("\n--- JSONL ---")
with open("data.jsonl", "r", encoding="utf-8") as f:
for line in f:
rec = json.loads(line)
print(rec)
৬ · pathlib — modern path handling
from pathlib import Path
# Path object — OS-independent
data_dir = Path("datasets")
file_path = data_dir / "students.csv" # / operator!
print(file_path)
print(file_path.suffix) # .csv
print(file_path.stem) # students
print(file_path.exists())
# Directory তৈরি
data_dir.mkdir(exist_ok=True)
# পড়া — Path-এর built-in
content = Path("hello.txt").read_text(encoding="utf-8")
print(content[:30])
# সব .csv খুঁজে বের
for csv_file in Path(".").glob("*.csv"):
print(csv_file)
pathlib.Path Python 3.4+ থেকে। OS-independent — Windows-এ \ ও Linux-এ / auto-handle। আজকের best practice — os.path-এর জায়গায়।
৭ · AI-তে file I/O-র প্রয়োগ
- Dataset loading: CSV (tabular), JSONL (LLM), parquet (big-data)।
- Configuration: JSON/YAML hyperparameter।
- Model checkpoint: binary
.pt,.h5,.safetensors। - Logging: training logs, metrics CSV।
- Cache: embedding pre-compute → disk-এ।
- Output: prediction CSV → submission।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১
with open(...) বনাম open() + manual close — কেন context manager universally preferred? Resource leak কী, ও AI training-এ কীভাবে কামড় দেয়?
Context manager — Python-এর সবচেয়ে underrated feature। PEP 343 (২০০৫) থেকে। ভাল কোড ও bad কোডের সীমারেখা।
Resource leak কী?
- OS-এর প্রতিটি open file = একটি "file descriptor" (FD)।
- OS-এর FD limit আছে — Linux default 1024।
- Close না করলে — ধীরে ধীরে শেষ হয়।
- "Too many open files" error — production crash।
Without context manager:
f = open("data.txt")
process(f.read())
f.close() # বহু সমস্যা:
# 1. process() exception দিলে close চলে না
# 2. মনে রাখা দরকার
# 3. early return — close মিস
With context manager:
with open("data.txt") as f:
process(f.read())
# yes — exception হলেও close
# yes — early return-এ close
# yes — visual scope spell out
Mechanism — __enter__/__exit__:
class MyContext:
def __enter__(self):
# setup (open file, acquire lock)
return self
def __exit__(self, exc_type, exc, tb):
# cleanup (close, release)
return False # exception propagate
AI training-এ resource leak-এর কামড়:
- Training loop-এ file open করলে: ১০,০০০ epoch → ১০,০০০ FD leak → crash।
- DataLoader worker-এ: প্রতি batch file open — কিন্তু close না হলে।
- Weights & Biases / TensorBoard: log writer সঠিক close না হলে — buffer flush হয় না, data lost।
- GPU memory: tensor leak — analogous problem। PyTorch-এ
torch.cuda.empty_cache()।
Beyond files — context manager-এর ব্যবহার:
with torch.no_grad():— gradient computation disable।with model.eval():— eval mode।with timer():— section timing।with Lock():— thread synchronization।with db.transaction():— atomic operation।
Custom context manager — easy way:
from contextlib import contextmanager
@contextmanager
def timer(name):
import time
start = time.time()
yield
print(f"{name}: {time.time()-start:.4f}s")
with timer("training"):
train_one_epoch()
Multiple resources:
# একসাথে দুই ফাইল
with open("in.txt") as f_in, open("out.txt", "w") as f_out:
f_out.write(f_in.read().upper())
# Python 3.10+ — parenthesized
with (
open("a.txt") as a,
open("b.txt") as b,
open("c.txt") as c,
):
...
মূল উপলব্ধি: with = "guarantee cleanup"। AI long-running training-এ অপরিহার্য। File, lock, DB, GPU memory — যেকোনো resource। মন দিয়ে গাঁথা — লাখ epoch-এও crash নেই।
প্র ০২ JSON, JSONL, Parquet, HDF5 — চারটি data format। Big AI dataset-এর জন্য কোনটা সেরা? Trade-off কী — readability, size, speed, schema-evolution?
Data format choice = AI infrastructure-এর foundational decision। ভুল choice = TB-scale data দিয়ে বছর হারানো।
JSON — universal, readable:
- ✓ Human-readable, debug সহজ।
- ✓ Universal — সব ভাষায়।
- ✓ Schema flexible।
- ✗ Large — text overhead।
- ✗ Slow parse — character-by-character।
- ✗ Single object — পুরোটা memory-তে।
JSONL — streaming-friendly:
- প্রতি লাইনে একটি JSON object।
- ✓ Stream-friendly — generator দিয়ে।
- ✓ Append চলে — concurrent write।
- ✓ Partial read — corrupt লাইন skip।
- ✓ HuggingFace, OpenAI fine-tuning — standard।
- ✗ Still text — large size।
- ✗ Random access নেই।
Parquet — columnar binary:
- Apache project (২০১৩) — Hadoop ecosystem থেকে।
- ✓ Compressed — JSON-এর ১০-১০০× ছোট।
- ✓ Columnar — শুধু দরকারি column পড়া যায়।
- ✓ Schema-aware — type checking।
- ✓ Predicate pushdown — filter at read time।
- ✓ Pandas, Spark, Dask — সবাই native।
- ✗ Binary — debug কঠিন।
- ✗ Append কঠিন।
HDF5 — scientific:
- NASA-র scientific data থেকে এসেছে।
- ✓ Hierarchical — ফাইলের মধ্যে dataset tree।
- ✓ Random access — slice load।
- ✓ Multi-dimensional array native।
- ✓ TF/PyTorch compatible।
- ✗ Concurrent write কঠিন।
- ✗ Library-heavy।
আধুনিক alternatives:
- Arrow/Feather: in-memory columnar — দ্রুত। Pandas-এর সাথে natural।
- Zarr: Cloud-native HDF5 alternative। Object storage friendly।
- WebDataset: tar archive — streaming + sharded。 PyTorch-এর জন্য আদর্শ।
- safetensors: Hugging Face — secure, fast tensor format।
Use case-ভিত্তিক recommendation:
- Configuration: JSON/YAML/TOML।
- LLM training data: JSONL — streaming।
- Tabular ML data < 10 GB: Parquet।
- Tabular ML data > 100 GB: Parquet + partitioning।
- Scientific multi-D arrays: HDF5/Zarr।
- Image/audio batches: WebDataset।
- Model weights: safetensors > .pt।
Performance comparison (১ লক্ষ tabular row):
- JSON: ৫০ MB, ১.৫ s read।
- JSONL: ৫০ MB, ১.০ s।
- CSV: ৩০ MB, ০.৫ s।
- Parquet: ৩ MB, ০.০৫ s — best।
Schema evolution challenges:
- JSON/JSONL — flexible, কিন্তু runtime error risk।
- Parquet — schema embedded, evolution support।
- Arrow — strict typing।
- Pydantic + JSONL = balance।
মূল উপলব্ধি: "One format fits all" নেই। Workflow stage-অনুযায়ী format। Raw collection JSONL → cleaned/processed Parquet → training তৈরি Arrow। AI infra-র এই pipeline বুঝলে — petabyte data scale-এ যেতে পারবেন।
প্র ০৩ Encoding সমস্যা (UnicodeDecodeError) Python-এর একটি classic pain. UTF-8, UTF-16, ASCII, Latin-1 — পার্থক্য কী? Bangla প্রকল্পে কোন সাবধানতা?
Encoding — software engineering-এর সবচেয়ে underestimated topic। ভুল encoding = silent data corruption।
মূল ধারণা:
- Computer-এ "অক্ষর" নেই — শুধু bytes (০-২৫৫)।
- Encoding = "এই byte কোন অক্ষর?" mapping।
- ভুল encoding-এ পড়া = mojibake (গরবলা)।
Encoding-এর historical evolution:
- ASCII (১৯৬৩): ৭-bit, ১২৮ char। English only।
- Latin-1/ISO-8859-1: ৮-bit, ২৫৬ char। European।
- Windows-1252: Microsoft variant। প্রায়ই Western default।
- ISCII, ASCII-Bangla: পুরনো Bangla — incompatible।
- UTF-8 (১৯৯৩): Unicode + ASCII compatible. ১-৪ bytes/char।
- UTF-16: Java, JavaScript। ২-৪ bytes।
UTF-8 কেন winner?
- ASCII subset — backward compatible।
- Variable length — English এ ১ byte, Bangla এ ৩ bytes।
- Self-synchronizing — partial corrupt-এ recovery।
- Web-এর de facto (98%+ pages)।
- Python ৩-এর default।
Bangla-র specifics:
- Bangla Unicode range: U+0980 - U+09FF।
- প্রতি অক্ষর — UTF-8-এ ৩ bytes (সাধারণত)।
- Conjuncts (যুক্তবর্ণ) — multiple codepoints।
- Normalization (NFC, NFD) — same character ভিন্ন bytes।
সাধারণ Bangla bug:
# Windows default cp1252 → Bangla broken
with open("bangla.txt") as f:
text = f.read() # UnicodeDecodeError
# Always explicit
with open("bangla.txt", encoding="utf-8") as f:
text = f.read() # ✓
Detection ও handling:
# Detect — chardet library
import chardet
with open("unknown.txt", "rb") as f:
raw = f.read()
detected = chardet.detect(raw)
print(detected) # {'encoding': 'utf-8', 'confidence': 0.99}
# Errors handling
text = raw.decode("utf-8", errors="replace") # ? for invalid
text = raw.decode("utf-8", errors="ignore") # silent skip
BOM (Byte Order Mark):
- UTF-8 BOM:
\xef\xbb\xbf - Excel CSV save করলে — BOM যোগ করে। Python-এ extra char।
- Solution:
encoding="utf-8-sig"
Normalization issue:
import unicodedata
# একই display, ভিন্ন bytes
a = "নী" # NFC — single codepoint
b = "নী" # NFD — two codepoints
print(a == b) # False!
print(unicodedata.normalize("NFC", a) ==
unicodedata.normalize("NFC", b)) # True
AI/ML-এ encoding সাবধানতা:
- Tokenizer training — সঠিক normalization জরুরি।
- Multilingual models — UTF-8 explicit।
- Web scraping — chardet detect।
- Database export — UTF-8 with BOM-এর জন্য সাবধান।
- HuggingFace tokenizer — pre-tokenization-এ Unicode normalize।
সর্বদা practice:
encoding="utf-8"EVERYWHERE।- Source file BOM-free UTF-8।
- Locale-independent code (LANG=C.UTF-8)।
- Test multilingual data।
- Normalize Unicode (NFC) at boundary।
মূল উপলব্ধি: Encoding bugs silent ও subtle। Bangla project-এ — UTF-8 explicit always। Decode early at boundary, work in str, encode at boundary again। "Garbage in, garbage out" — encoding-এর জগতে literal।
প্র ০৪ "Open file in loop" anti-pattern বনাম "open once, iterate" — performance ও correctness-এ পার্থক্য কী? Memory-mapped file কখন? AI dataset training-এ এই choice-এর প্রভাব?
File access patterns — performance-এর hidden lever। AI-তে correct pattern = ১০× faster training।
Anti-pattern: open in loop:
# খুব খারাপ — প্রতি batch-এ file open
for batch_idx in range(1000):
with open("data.csv") as f:
data = f.read()
process(data)
# 1000× file open — slow, FD pressure
সঠিক — open একবার:
# ভাল
data = []
with open("data.csv") as f:
for line in f:
data.append(parse(line))
for batch in batches(data):
process(batch)
কিন্তু — সমস্যা: data যদি ১০০ GB?
- সব memory-তে — RAM exhausted।
- Generator pattern দরকার।
Streaming pattern:
def stream_batches(path, batch_size=32):
with open(path) as f:
batch = []
for line in f:
batch.append(parse(line))
if len(batch) == batch_size:
yield batch
batch = []
if batch:
yield batch
for batch in stream_batches("huge.jsonl"):
train_step(batch)
Memory-mapped file (mmap):
import mmap
with open("huge.bin", "rb") as f:
mm = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
# OS lazily loads pages as accessed
# Random access to TBs without memory pressure
chunk = mm[1000:2000]
mm.close()
mmap-এর জাদু:
- OS file pages-কে virtual memory-তে map করে।
- Read করলেই — page-fault → disk → cache।
- Multiple process একই file share করতে পারে।
- Random access constant time — even for 100 GB।
AI training data access patterns:
- Sequential: stream — generator, simplest।
- Random shuffle: all-in-memory if fits, else mmap বা index-based।
- Sharded: WebDataset — tar shards, parallel read।
- Distributed: S3/GCS streaming, prefetch।
PyTorch DataLoader internals:
- num_workers — multi-process file read।
- pin_memory — pinned buffer for GPU transfer।
- prefetch — পরের batch প্রস্তুত করে।
- persistent_workers — worker reuse।
I/O bottleneck-এর symptom:
- GPU utilization < 50% — data pipeline bottleneck।
- Disk activity 100% — I/O bound।
- Solution: parallel read, faster format (Parquet), SSD।
Benchmarking command:
# Linux
iostat -x 1
nvidia-smi --query-gpu=utilization.gpu --format=csv -l 1
Best practices summary:
- Open once, iterate inside.
- Generator for streaming।
- mmap for random access on large files।
- Parquet/Arrow for tabular।
- WebDataset for shard-based training।
- Profile before optimizing।
মূল উপলব্ধি: File I/O = AI training-এর hidden bottleneck। Compute powerful, কিন্তু data feed slow → GPU idle। Right pattern (open once, generator, mmap, sharding) = full GPU utilization। L19+ Notebook ও Pandas-এ আমরা এই pattern বাস্তবিক দেখব।
অনুশীলন
-
Word counter: একটি text ফাইল লিখুন (৫টি বাংলা বাক্য)। তারপর পড়ে — মোট কতটি লাইন ও word আছে গণনা করুন।
# লেখা text = """বাংলা আমার মাতৃভাষা। পাইথন একটি জনপ্রিয় ভাষা। AI ভবিষ্যৎ গড়বে। ABCL TECH-এ আমরা শিখছি। ফাইল I/O সহজ।""" with open("sample.txt", "w", encoding="utf-8") as f: f.write(text) # পড়া + গণনা with open("sample.txt", "r", encoding="utf-8") as f: lines = f.readlines() n_lines = len(lines) n_words = sum(len(line.split()) for line in lines) print(f"লাইন: {n_lines}, শব্দ: {n_words}") -
JSON config: একটি hyperparameter dict তৈরি করুন (lr, batch, epochs)। JSON-এ save ও পরে load করুন।
import json cfg = {"lr": 0.001, "batch": 32, "epochs": 50} with open("hparams.json", "w") as f: json.dump(cfg, f, indent=2) with open("hparams.json") as f: loaded = json.load(f) print(loaded) print(f"Learning rate: {loaded['lr']}") -
CSV → average: একটি CSV-তে student scores লিখুন। পড়ে — গড় score বের করুন DictReader দিয়ে।
import csv # তৈরি rows = [ ["name", "score"], ["A", 85], ["B", 92], ["C", 78], ["D", 67], ["E", 95] ] with open("scores.csv", "w", newline="", encoding="utf-8") as f: csv.writer(f).writerows(rows) # গড় with open("scores.csv", encoding="utf-8") as f: reader = csv.DictReader(f) scores = [int(row["score"]) for row in reader] avg = sum(scores) / len(scores) print(f"গড় স্কোর: {avg:.2f}") # 83.40
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পাঠ ০৮ · Error handling ও exception পরবর্তী পাঠ File-not-found, permission, encoding error সামলানোর উপায়।
- পাঠ ০৬ · List comprehension ও iterator আগের পাঠ
- পাঠ ১৪ · CSV পড়া ও পরিষ্কার এগিয়ে যান Pandas-এ CSV — production-ready।
- সব AI Courses দেখুন ABCL TECH