
প্রোগ্রাম বন্ধ করলেই সব তথ্য হারিয়ে যায়, এই সমস্যাটি নতুন প্রোগ্রামারদের প্রথম বড় হোঁচট। ভ্যারিয়েবলে রাখা মান কম্পিউটারের র্যামে থাকে, আর প্রোগ্রাম শেষ হওয়ামাত্র সেই জায়গা মুছে যায়। তথ্য ধরে রাখতে হলে সেটিকে ডিস্কে, অর্থাৎ একটি ফাইলে লিখে রাখতে হয়।
এই টিউনে আমরা একটি ছোট নোট অ্যাপ বানাব যা লেখা নোটগুলো ফাইলে জমা রাখবে এবং প্রোগ্রাম আবার চালু করলে সেগুলো ফিরিয়ে আনবে। পুরোনো পদ্ধতি BufferedWriter ও BufferedReader দিয়ে শুরু করব, তারপর দেখব আধুনিক Files ক্লাস দিয়ে একই কাজ কত কম লাইনে করা যায়। বাংলা লেখা ফাইলে সঠিকভাবে রাখার কৌশলটিও থাকবে, যেটি না জানলে বাংলা অক্ষর প্রশ্নবোধক চিহ্ন হয়ে যায়।
অ্যাপটি চালু হলে একটি ছোট মেনু দেখাবে। ব্যবহারকারী নতুন নোট লিখতে পারবেন, আগের সব নোট দেখতে পারবেন, অথবা বের হয়ে যেতে পারবেন। প্রতিটি নোট notes.txt নামের একটি ফাইলে নতুন লাইন হিসেবে যোগ হবে।
ফাইলে লেখার জন্য FileWriter যথেষ্ট, তবে তার উপরে BufferedWriter মুড়ে দিলে বারবার ডিস্কে না গিয়ে একসাথে লেখা হয়, ফলে গতি বাড়ে। নিচের কোডে দুটি গুরুত্বপূর্ণ জিনিস আছে, খেয়াল করুন।
static void saveNote(String note) {try (BufferedWriter writer = new BufferedWriter(new FileWriter("notes.txt", StandardCharsets.UTF_8, true))) {writer.write(note); writer.newLine(); System.out.println("নোট সেভ হয়েছে");} catch (IOException e) {System.out.println("সেভ করা যায়নি, কারণ " + e.getMessage());}শুধু নাম দিলে ফাইলটি প্রোগ্রামের ওয়ার্কিং ডিরেক্টরিতে তৈরি হয়, যা সাধারণত প্রজেক্ট ফোল্ডার। কোথায় হলো তা নিশ্চিত হতে System.getProperty দিয়ে user.dir ছাপিয়ে দেখুন, তাহলে আর খুঁজে বেড়াতে হবে না।
পড়ার সময় আমরা একটি লুপ চালাব যা প্রতিটি লাইন এক এক করে আনবে। readLine মেথডটি ফাইলের শেষে পৌঁছালে null ফেরত দেয়, সেটিই আমাদের থামার সংকেত।
static void showNotes() {try (BufferedReader reader = new BufferedReader(new FileReader("notes.txt", StandardCharsets.UTF_8))) {String line; int count = 1; while (line = reader.readLine())!= null) {System.out.println(count + ". " + line); count+;} catch (IOException e) {System.out.println("এখনো কোনো নোট নেই");}জাভার আধুনিক Files ক্লাস ব্যবহার করলে উপরের কাজগুলো মাত্র দুই লাইনে হয়ে যায়। ছোট ফাইলের জন্য এটিই এখন সবচেয়ে পরিষ্কার পদ্ধতি।
Path path = Path.of("notes.txt");
Files.writeString(path, "নতুন একটি নোট" + System.lineSeparator(), StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
String all = Files.readString(path, StandardCharsets.UTF_8);
System.out.println(all);এবার সব অংশ একসাথে জুড়ে দিচ্ছি। Scanner দিয়ে ব্যবহারকারীর পছন্দ নেব, while লুপ দিয়ে বারবার মেনু দেখাব, আর switch দিয়ে কাজ ভাগ করব।
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class NoteApp {private static final String FILE = "notes.txt"; public static void main(String[] args) {Scanner scanner = new Scanner(System.in); boolean running = true; while (running) {System.out.println(); System.out.println("1. নতুন নোট লিখুন"); System.out.println("2. সব নোট দেখুন"); System.out.println("3. বের হয়ে যান"); System.out.print("আপনার পছন্দ: "); String choice = scanner.nextLine().trim(); switch (choice) {case "1": System.out.print("নোট লিখুন: "); saveNote(scanner.nextLine()); break; case "2": showNotes(); break; case "3": running = false; System.out.println("ধন্যবাদ"); break; default: System.out.println("1, 2 অথবা 3 লিখুন");} scanner.close();} static void saveNote(String note) {if (note.isBlank()) {System.out.println("খালি নোট সেভ করা যাবে না"); return;} try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILE, StandardCharsets.UTF_8, true))) {writer.write(note); writer.newLine(); System.out.println("নোট সেভ হয়েছে");} catch (IOException e) {System.out.println("সেভ করা যায়নি, কারণ " + e.getMessage());} static void showNotes() {try (BufferedReader reader = new BufferedReader(new FileReader(FILE, StandardCharsets.UTF_8))) {String line; int count = 1; while (line = reader.readLine())!= null) {System.out.println(count + ". " + line); count+;} if (count = 1) {System.out.println("তালিকা খালি");} catch (IOException e) {System.out.println("এখনো কোনো নোট নেই");}এটি এনকোডিংয়ের সমস্যা। FileWriter ও FileReader দুই জায়গাতেই StandardCharsets.UTF 8 দিতে হবে, একটিতে দিলে অন্যটিতে ভুল হবে। যে টেক্সট এডিটরে ফাইলটি খুলে দেখছেন সেটিও যেন UTF 8 এ পড়ে সেদিকে খেয়াল রাখুন।
FileWriter এর দ্বিতীয় বা তৃতীয় প্যারামিটারে true দিতে ভুলে গেছেন। ওই মানটিই ঠিক করে দেয় নতুন লেখা আগেরটির উপরে বসবে নাকি শেষে যোগ হবে।
Scanner এর সাথে nextInt ও nextLine মিশিয়ে ব্যবহার করলে এই সমস্যা হয়, কারণ nextInt লাইনের শেষের অংশটি রেখে দেয়। সবচেয়ে নিরাপদ উপায় হলো সব ইনপুট nextLine দিয়ে নেওয়া, তারপর প্রয়োজনে সংখ্যায় রূপ দেওয়া, যা আমরা এই প্রোগ্রামে করেছি।
ফাইল পড়া ও লেখা শিখে ফেলা মানে আপনার প্রোগ্রাম আর ক্ষণস্থায়ী নয়। একই কৌশলে আপনি ছাত্রছাত্রীর নম্বর, খরচের হিসাব বা ছোট ইনভেন্টরি, সবই সংরক্ষণ করতে পারবেন। ডেটাবেজ শেখার আগে এই ধাপটি পার হওয়া খুব জরুরি, কারণ ধারণাগুলো একই থাকে।
অ্যাপটি চালিয়ে দেখুন, তারপর নিজে একটি সুবিধা যোগ করুন, যেমন নির্দিষ্ট শব্দ দিয়ে নোট খোঁজার ব্যবস্থা। কোন জায়গায় আটকে যাচ্ছেন টিউমেন্টে লিখে জানান, আলোচনা করলে সমাধান দ্রুত আসে।
আমি নাছিরুল হক। বিশ্বের সর্ববৃহৎ বিজ্ঞান ও প্রযুক্তির সৌশল নেটওয়ার্ক - টেকটিউনস এ আমি 15 ঘন্টা 26 মিনিট যাবৎ যুক্ত আছি। টেকটিউনস আমি এ পর্যন্ত 9 টি টিউন ও 0 টি টিউমেন্ট করেছি। টেকটিউনসে আমার 0 ফলোয়ার আছে এবং আমি টেকটিউনসে 0 টিউনারকে ফলো করি।