Java দিয়ে ফাইলে নোট সেভ ও পড়ার অ্যাপ তৈরি, BufferedWriter থেকে Files API পর্যন্ত হাতে কলমে গাইড

টিউন বিভাগ জাভা
প্রকাশিত

প্রোগ্রাম বন্ধ করলেই সব তথ্য হারিয়ে যায়, এই সমস্যাটি নতুন প্রোগ্রামারদের প্রথম বড় হোঁচট। ভ্যারিয়েবলে রাখা মান কম্পিউটারের র্যামে থাকে, আর প্রোগ্রাম শেষ হওয়ামাত্র সেই জায়গা মুছে যায়। তথ্য ধরে রাখতে হলে সেটিকে ডিস্কে, অর্থাৎ একটি ফাইলে লিখে রাখতে হয়।

এই টিউনে আমরা একটি ছোট নোট অ্যাপ বানাব যা লেখা নোটগুলো ফাইলে জমা রাখবে এবং প্রোগ্রাম আবার চালু করলে সেগুলো ফিরিয়ে আনবে। পুরোনো পদ্ধতি BufferedWriter ও BufferedReader দিয়ে শুরু করব, তারপর দেখব আধুনিক Files ক্লাস দিয়ে একই কাজ কত কম লাইনে করা যায়। বাংলা লেখা ফাইলে সঠিকভাবে রাখার কৌশলটিও থাকবে, যেটি না জানলে বাংলা অক্ষর প্রশ্নবোধক চিহ্ন হয়ে যায়।

যা যা লাগবে

  • কম্পিউটারে JDK 17 বা তার চেয়ে নতুন ভার্সন, কারণ আমরা Files.readString মেথডটি ব্যবহার করব
  • IntelliJ IDEA Community Edition অথবা VS Code
  • লুপ, শর্ত ও মেথড লেখার প্রাথমিক অভ্যাস
  • টার্মিনাল বা কনসোলে টাইপ করে প্রোগ্রামের সাথে কথা বলার আগ্রহ

যে অ্যাপটি বানাব

অ্যাপটি চালু হলে একটি ছোট মেনু দেখাবে। ব্যবহারকারী নতুন নোট লিখতে পারবেন, আগের সব নোট দেখতে পারবেন, অথবা বের হয়ে যেতে পারবেন। প্রতিটি নোট notes.txt নামের একটি ফাইলে নতুন লাইন হিসেবে যোগ হবে।

  • নতুন নোট যোগ হবে, আগেরগুলো মুছবে না
  • ফাইল না থাকলে প্রোগ্রাম ভাঙবে না, বরং বোধগম্য বার্তা দেখাবে
  • বাংলা লেখা ফাইলে হুবহু বাংলা হয়েই থাকবে
  • ফাইল বন্ধ করার কাজটি জাভা নিজেই করবে, আমাদের মনে রাখতে হবে না

ধাপ ১: ফাইলে লেখা, BufferedWriter দিয়ে

ফাইলে লেখার জন্য 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());}
  • শেষের true মানটির নাম append, এটি না দিলে প্রতিবার লেখার সময় পুরোনো সব লেখা মুছে যাবে
  • StandardCharsets.UTF 8 দেওয়ায় বাংলা অক্ষর সঠিকভাবে সংরক্ষিত হবে
  • newLine মেথডটি প্রতিটি নোটকে আলাদা লাইনে রাখে, তাই পরে পড়ার সময় আলাদা করা সহজ হয়
  • try এর বন্ধনীর ভেতরে রিসোর্স খোলার এই নিয়মটির নাম try with resources, কাজ শেষে জাভা নিজেই ফাইলটি বন্ধ করে দেয়

ফাইলটি আসলে কোথায় তৈরি হলো

শুধু নাম দিলে ফাইলটি প্রোগ্রামের ওয়ার্কিং ডিরেক্টরিতে তৈরি হয়, যা সাধারণত প্রজেক্ট ফোল্ডার। কোথায় হলো তা নিশ্চিত হতে System.getProperty দিয়ে user.dir ছাপিয়ে দেখুন, তাহলে আর খুঁজে বেড়াতে হবে না।

ধাপ ২: ফাইল থেকে পড়া, BufferedReader দিয়ে

পড়ার সময় আমরা একটি লুপ চালাব যা প্রতিটি লাইন এক এক করে আনবে। 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("এখনো কোনো নোট নেই");}
  • বন্ধনীর ভেতরে একসাথে মান বসানো ও যাচাই করা হচ্ছে, এই লেখার ধরনটি ফাইল পড়ার ক্ষেত্রে খুব প্রচলিত
  • ফাইল না থাকলে FileNotFoundException আসে, যা IOException এর ভেতরেই ধরা পড়ে
  • ব্যবহারকারীকে ভীতিকর এরর না দেখিয়ে সহজ বাংলা বার্তা দেখানো হয়েছে

ধাপ ৩: Files ক্লাস দিয়ে একই কাজ কম লাইনে

জাভার আধুনিক 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);
  • StandardOpenOption.CREATE বলছে ফাইল না থাকলে বানিয়ে নাও
  • StandardOpenOption.APPEND বলছে আগের লেখা মুছো না, শেষে যোগ করো
  • System.lineSeparator ব্যবহার করলে উইন্ডোজ ও লিনাক্স দুই জায়গাতেই লাইন ভাঙা ঠিকভাবে কাজ করে
  • তবে খুব বড় ফাইলের ক্ষেত্রে readString ব্যবহার করবেন না, কারণ পুরো ফাইল একসাথে মেমোরিতে উঠে আসে

ধাপ ৪: মেনু চালিত সম্পূর্ণ প্রোগ্রাম

এবার সব অংশ একসাথে জুড়ে দিচ্ছি। 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 দিতে ভুলে গেছেন। ওই মানটিই ঠিক করে দেয় নতুন লেখা আগেরটির উপরে বসবে নাকি শেষে যোগ হবে।

NoSuchElementException এসে প্রোগ্রাম বন্ধ হয়ে যাচ্ছে

Scanner এর সাথে nextInt ও nextLine মিশিয়ে ব্যবহার করলে এই সমস্যা হয়, কারণ nextInt লাইনের শেষের অংশটি রেখে দেয়। সবচেয়ে নিরাপদ উপায় হলো সব ইনপুট nextLine দিয়ে নেওয়া, তারপর প্রয়োজনে সংখ্যায় রূপ দেওয়া, যা আমরা এই প্রোগ্রামে করেছি।

শেষ কথা

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

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

Level 0

আমি নাছিরুল হক। বিশ্বের সর্ববৃহৎ বিজ্ঞান ও প্রযুক্তির সৌশল নেটওয়ার্ক - টেকটিউনস এ আমি 15 ঘন্টা 26 মিনিট যাবৎ যুক্ত আছি। টেকটিউনস আমি এ পর্যন্ত 9 টি টিউন ও 0 টি টিউমেন্ট করেছি। টেকটিউনসে আমার 0 ফলোয়ার আছে এবং আমি টেকটিউনসে 0 টিউনারকে ফলো করি।


টিউনস


আরও টিউনস


টিউনারের আরও টিউনস


টিউমেন্টস