Java File I/O: ගොනු කියවීම සහ ලිවීම SC Guide

Java File I/O: ගොනු කියවීම සහ ලිවීම SC Guide

Java File I/O Essentials: ගොනු එක්ක වැඩ කරමු SC Guide!

ආයුබෝවන් මචංලා! කොහොමද හැමෝටම? ඔයාලා දන්නවනේ, අපි මොන Software එක හැදුවත්, සමහර වෙලාවට අපිට Data ටිකක් File එකක Save කරගන්න, නැත්නම් කලින් Save කරපු Data ටිකක් කියවගන්න වෙනවා. උදාහරණයක් විදිහට, ඔයාලා Student Management System එකක් හැදුවොත්, Student ලගේ Details ටික Database එකක Save කරනවා වගේම, සමහර විට Report එකක් Text File එකකට Print කරන්නත්, නැත්නම් Excel File එකකින් Data Import කරන්නත් ඕන වෙන්න පුළුවන්. අන්න එතකොට තමයි Java File I/O (Input/Output) අපේ ගලවාගන්නට එන්නේ!

අද අපි කතා කරමු Java වල File I/O කියන්නේ මොකක්ද, ඒක කොහොමද වැඩ කරන්නේ, ඒ වගේම අපිට ගොඩක්ම ප්‍රයෝජනවත් වෙන FileInputStream, FileOutputStream, BufferedReader වගේ Classes ටිකක් පාවිච්චි කරලා Files Read කරන හැටි සහ Write කරන හැටි. අපි සරල Code Examples එක්කම මේවා බලමු, එතකොට ඔයාලට Practical විදිහටම තේරෙයි!

File I/O කියන්නේ මොකක්ද? (Input/Output Basics)

ඉතින්, මුලින්ම බලමු File I/O කියන්නේ මොකක්ද කියලා. සරලවම කිව්වොත්, I/O කියන්නේ Input/Output. මේකෙන් වෙන්නේ Program එකක් ඇතුළට Data ගන්න එක (Input) සහ Program එකෙන් පිටතට Data යවන එක (Output). Files කියන්නේ මේ Data ටික ස්ථීරවම (Persistently) ගබඩා කරලා තියාගන්න පුළුවන් තැන්. Hard Drive එකේ, SSD එකේ වගේ තැන්වල තමයි මේ Files තියෙන්නේ.

Java වලදී Files එක්ක වැඩ කරන්න අපි Streams පාවිච්චි කරනවා. Stream එකක් කියන්නේ Data ගලන Pipe එකක් වගේ දෙයක්. Data එක පැත්තකින් ඇතුල් වෙලා, අනිත් පැත්තෙන් එලියට යනවා. Java වල Stream Types දෙකක් තියෙනවා:

  1. Byte Streams: මේවා Use කරන්නේ Binary Data (Images, Audio, Video, compressed files) Read කරන්න සහ Write කරන්න. මේවා byte එකින් එක Process කරනවා. FileInputStream සහ FileOutputStream මේ ගණයට වැටෙනවා.
  2. Character Streams: මේවා Use කරන්නේ Text Data (Plain Text files) Read කරන්න සහ Write කරන්න. මේවා Character Set එකක් (ASCII, Unicode) පාවිච්චි කරලා Characters විදිහට Data Process කරනවා. FileReader, FileWriter, BufferedReader, BufferedWriter මේ ගණයට වැටෙනවා.

අපි මේ දෙකම පාවිච්චි කරන හැටි අද බලමු!

File වලට ලියමු! (Writing to Files with FileOutputStream)

මුලින්ම බලමු අපි කොහොමද File එකකට Data Write කරන්නේ කියලා. අපි FileOutputStream කියන Class එක පාවිච්චි කරමු. මේක Byte Stream එකක්. මේකෙන් අපිට Bytes විදිහට File එකකට Data යවන්න පුළුවන්.

FileOutputStream භාවිතය

FileOutputStream එකක් හදද්දි, අපි File Path එකක් දෙනවා. ඒ File එක නැත්නම්, මේක Automatically File එක හදනවා. File එක තියෙනවා නම්, කලින් තිබ්බ Data ටික අයින් කරලා අලුතෙන් ලියනවා. ඒක වළක්වන්න ඕන නම්, Constructor එකේදී true කියලා දෙවෙනි Parameter එකක් දෙන්න පුළුවන්. එතකොට Appending වෙන්නේ. (කලින් තිබ්බ Data වලට අලුත් Data එකතු වෙනවා).

අපි මේ Simple Code Example එක බලමු:

import java.io.FileOutputStream;
import java.io.IOException;

public class FileWriteExample {
    public static void main(String[] args) {
        String data = "Hello SC Guide! This is some data to write into a file. ";
        // Define the file path. Adjust this path as needed.
        String filePath = "output.txt"; 

        // try-with-resources ensures the stream is closed automatically
        try (FileOutputStream fos = new FileOutputStream(filePath)) {
            byte[] bytes = data.getBytes(); // Convert string to bytes
            fos.write(bytes); // Write bytes to the file
            System.out.println("Data successfully written to " + filePath);
        } catch (IOException e) {
            // Handle any I/O errors
            System.err.println("Error writing to file: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

මේ Code එකේදී අපි output.txt කියන File එකට "Hello SC Guide! This is some data to write into a file." කියන String එක ලියනවා. මේකෙදි විශේෂයෙන් බලන්න ඕන දේ තමයි try-with-resources Block එක. මේක Use කලාම, අපිට අතින් fos.close() කරන්න ඕන වෙන්නේ නෑ. Program එක Run වෙලා ඉවර වෙනකොට, Java ම Automatically Stream එක Close කරනවා. මේක I/O Operations වලදී Best Practice එකක්. IOException එකක් එන්න පුළුවන් නිසා අපි ඒක catch කරනවා.

File වලින් කියවමු! (Reading from Files with FileInputStream)

හරි, දැන් අපි File එකකට Data ලිව්වනේ. ඒ ලිව්ව Data ටික ආපහු කියවගන්නේ කොහොමද කියලා බලමු. ඒකට අපි FileInputStream කියන Class එක පාවිච්චි කරනවා. මේකත් FileOutputStream වගේම Byte Stream එකක්.

FileInputStream භාවිතය

FileInputStream එකක් හදන්නත් File Path එකක් දෙනවා. මේකෙන් අපිට read() method එක පාවිච්චි කරලා Byte එකින් එක Read කරන්න පුළුවන්. නැත්නම් read(byte[] b) method එක පාවිච්චි කරලා Bytes Array එකක් විදිහට Read කරන්න පුළුවන්.

import java.io.FileInputStream;
import java.io.IOException;

public class FileReadExample {
    public static void main(String[] args) {
        // Define the file path. Should be the same file written previously.
        String filePath = "output.txt"; 

        try (FileInputStream fis = new FileInputStream(filePath)) {
            int i; // To store each byte read
            StringBuilder content = new StringBuilder();
            System.out.println("Reading from file: " + filePath);

            // Read byte by byte until the end of the file (-1 is returned)
            while ((i = fis.read()) != -1) {
                content.append((char) i); // Convert byte to char and append
            }
            System.out.println("File Content:\n" + content.toString());

        } catch (IOException e) {
            // Handle any I/O errors
            System.err.println("Error reading from file: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

මේ Code එකේදී අපි output.txt කියන File එකෙන් Data ටික Read කරනවා. fis.read() method එකෙන් Byte එකක් Read කරනවා. File එකේ Data ඉවර වුනාම ඒකෙන් -1 Return කරනවා. ඒක නිසා අපි while ((i = fis.read()) != -1) Condition එක පාවිච්චි කරනවා. Read කරපු Byte එක (char) i කියලා Type Cast කරලා String එකකට එකතු කරනවා. මේකෙදිත් try-with-resources Use කරලා තියෙන නිසා Stream එක Automatically Close වෙනවා.

Text Files එක්ක වැඩ කරමු (Working with Text Files: BufferedReader and BufferedWriter)

FileInputStream සහ FileOutputStream Use කරලා අපිට ඕනෑම File එකකින් Data Read කරන්න සහ Write කරන්න පුළුවන් වුණත්, Text Files එක්ක වැඩ කරනකොට Byte Stream වලට වඩා Character Streams ගොඩක් පහසුයි. ඒ වගේම Performance අතින් බැලුවම, Buffering Use කරන Stream Types ගොඩක් වේගවත්. ඒකට තමයි BufferedReader සහ BufferedWriter කියන Classes දෙක තියෙන්නේ.

මේවා Data එකපාරටම Read/Write නොකර, Buffer එකක තියාගෙන, Buffer එක පිරුණාම Read/Write කරනවා. මේ නිසා I/O Operations වලදී යන Time එක අඩු වෙනවා.

BufferedWriter භාවිතය (Writing Text Data Line by Line)

BufferedWriter Use කරනකොට, අපි ඒකට FileWriter එකක් දෙනවා. FileWriter එක Text Data Characters විදිහට File එකට ලියනවා. BufferedWriter එක ඒක Buffered කරනවා. අපිට newLine() method එකෙන් අලුත් Line එකක් පටන් ගන්නත් පුළුවන්.

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class TextFileWriteExample {
    public static void main(String[] args) {
        String filePath = "poem.txt";
        String[] lines = {
            "නැගී එන හිරු රැස් විහිදේ",
            "නුඹෙ මුහුණ මට මතකේ",
            "සිහිනයක්ද මේ මා දකින්නේ?",
            "අපේ ගමේ සුන්දරත්වය!"
        };

        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            for (String line : lines) {
                writer.write(line);
                writer.newLine(); // Write a new line character
            }
            System.out.println("Poem successfully written to " + filePath);
        } catch (IOException e) {
            System.err.println("Error writing text to file: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

මේ Code එකේදී අපි සිංහල කවි පේලි ටිකක් poem.txt කියන File එකට ලියනවා. newLine() method එකෙන් Line Break එකක් දානවා. FileWriter(filePath, true) කියලා දුන්නොත් File එකට Append කරන්නත් පුළුවන්.

BufferedReader භාවිතය (Reading Text Data Line by Line)

BufferedReader Use කරනකොට, අපි ඒකට FileReader එකක් දෙනවා. FileReader එක File එකෙන් Text Data Read කරනවා. BufferedReader එක ඒක Buffered කරනවා. මේකේ තියෙන ලොකුම පහසුව තමයි readLine() method එක. මේකෙන් අපිට Line එකින් එක Read කරන්න පුළුවන්.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class TextFileReadExample {
    public static void main(String[] args) {
        String filePath = "poem.txt";

        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            System.out.println("Reading from file: " + filePath);
            System.out.println("--------------------------------");

            // Read line by line until the end of the file (null is returned)
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            System.out.println("--------------------------------");
            System.out.println("Successfully read all lines from " + filePath);
        } catch (IOException e) {
            System.err.println("Error reading text from file: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

මේ Code එකේදී අපි poem.txt කියන File එකෙන් කවි පේලි ටික Read කරනවා. reader.readLine() method එකෙන් Line එකක් Read කරනවා. File එකේ Line ඉවර වුනාම ඒකෙන් null Return කරනවා. ඒක නිසා අපි while ((line = reader.readLine()) != null) Condition එක පාවිච්චි කරනවා.

වැදගත් දේවල් සහ Best Practices (Error Handling and Best Practices)

Files එක්ක වැඩ කරනකොට අපිට ගොඩක් වෙලාවට Errors එන්න පුළුවන්. File එකක් නැති වෙන්න පුළුවන් (FileNotFoundException), File එකකට ලියන්න හෝ කියවන්න Permissions නැති වෙන්න පුළුවන්. ඒ නිසා Error Handling කියන එක ගොඩක් වැදගත්.

try-with-resources: අපි Code Examples වල දැක්ක වගේ, try-with-resources Block එක I/O operations වලදී Use කරන එක ගොඩක්ම හොඳ පුරුද්දක්. මේකෙන් Stream එක අනිවාර්යයෙන්ම Automatically Close කරනවා, මොකද Streams Close නොකර තියන එකෙන් Resources Leak වෙන්න පුළුවන්, Program එකේ Performance එකට බලපෑම් කරන්න පුළුවන්, නැත්නම් File එක Corrupt වෙන්නත් පුළුවන්. ඒ නිසා මේක මතක තියාගන්න. මේක Java 7 වල ඉඳන් ආපු Feature එකක්.

Path Handling: File Paths දෙද්දී, Operating System එක අනුව Path එක වෙනස් වෙන්න පුළුවන් (Windows වල \, Linux/macOS වල /). මේකෙන් එන ගැටළු මඟහරවන්න java.nio.file.Paths class එක Use කරන්න පුළුවන්. උදාහරණයක් විදිහට: Path filePath = Paths.get("data", "subfolder", "myfile.txt");

Character Encoding: Text Files එක්ක වැඩ කරනකොට Character Encoding කියන එක ගොඩක් වැදගත්. විශේෂයෙන්ම සිංහල වගේ භාෂා වලදී Unicode (UTF-8) Use කරන එක අනිවාර්යයි. නැත්නම් අකුරු අවුල් වෙලා පේන්න පුළුවන්. FileWriter සහ FileReader වලට Encoding එක specify කරන්න පුළුවන්.

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;

public class EncodingExample {
    public static void main(String[] args) {
        String filePath = "sinhala_text.txt";
        String text = "හෙලෝ ලෝකයා! මෙය සිංහල පෙළකි.";

        // Writing with UTF-8 encoding
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, StandardCharsets.UTF_8))) {
            writer.write(text);
            System.out.println("Text written with UTF-8 encoding.");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Reading with UTF-8 encoding
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath, StandardCharsets.UTF_8))) {
            String readText = reader.readLine();
            System.out.println("Text read with UTF-8 encoding: " + readText);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

නිගමනය (Conclusion)

ඉතින් මචන්ලා, අද අපි Java වල File I/O ගැන ගොඩක් දේවල් කතා කළා. FileInputStream සහ FileOutputStream පාවිච්චි කරලා Binary Data Read/Write කරන හැටි, ඒ වගේම BufferedReader සහ BufferedWriter පාවිච්චි කරලා Text Data පහසුවෙන් Read/Write කරන හැටි ඔයාලා දැන් දන්නවා. try-with-resources වගේ Best Practices ගැනත් අපි කතා කළා. මේ Concepts ටික ඔයාලගේ Software Development Journy එකේදී ගොඩක්ම ප්‍රයෝජනවත් වෙයි.

වැදගත්ම දේ තමයි, මේ දේවල් ඉගෙනගෙන තනියම Practice කරන එක. තනියම Project එකක් හදන්න උත්සහ කරන්න. Customer Details File එකක Save කරන Program එකක්, නැත්නම් Simple Diary App එකක් වගේ දෙයක් හදන්න උත්සහ කරන්න. මොකද, කරලා ඉගෙනගන්න එක තමයි හොඳම දේ!

මේ Article එක ගැන ඔයාලගේ අදහස් Comment Section එකේ දාන්න අමතක කරන්න එපා. මොනවා හරි ප්‍රශ්න තියෙනවා නම් අහන්න. ඊළඟ Article එකෙන් හම්බවෙමු! ජයවේවා!