Writing Files (File ထဲကို ဒေတာ ရေးခြင်း)
B2.5.1: Construct code to perform file-processing operations: open files in write/append mode, write to files, close files.
မြန်မာလို: file တွေနဲ့ အလုပ်လုပ်တဲ့ code ကို ကိုယ်တိုင် ရေးနိုင်ရပါမယ်: file ကို write mode (ရေးဖို့ ဖွင့်တဲ့ mode) ဒါမှမဟုတ် append mode (ရှိပြီးသား file ရဲ့ နောက်မှာ ဆက်ရေးတဲ့ mode) နဲ့ ဖွင့်ခြင်း၊ file ထဲ ရေးခြင်း၊ file ကို ပိတ်ခြင်း။
အဓိက အယူအဆများ
FileWriter နဲ့ ရေးခြင်း
FileWriter (file ထဲ စာရေးတဲ့ Java class) က file ထဲကို စာသား ရေးပေးပါတယ်။ ပုံမှန်အားဖြင့် (default) ရှိပြီးသား content (file ထဲမှာ ရှိနေတဲ့ အကြောင်းအရာ) မှန်သမျှကို overwrite (ဖျက်ပြီး အသစ် ရေးခြင်း) လုပ်ပါတယ်။
import java.io.FileWriter;
import java.io.IOException;
try {
FileWriter writer = new FileWriter("output.txt");
writer.write("Alice,85\n");
writer.write("Bob,72\n");
writer.write("Charlie,91\n");
writer.close();
System.out.println("File written successfully.");
} catch (IOException e) {
System.out.println("Error writing file: " + e.getMessage());
}
try:
f = open("output.txt", "w") # "w" = write mode - overwrites existing content
f.write("Alice,85\n")
f.write("Bob,72\n")
f.write("Charlie,91\n")
f.close()
print("File written successfully.")
except OSError: # OSError is Python's IOException - raised when writing fails
print("Error writing file.")
writer.close() ကို အမြဲ ခေါ်ပါ။ မပိတ်ရင် ဒေတာတွေက buffer (file ထဲ မရေးရသေးတဲ့ ဒေတာကို ခဏ သိမ်းထားတဲ့ memory နေရာ) ထဲမှာ ကျန်နေပြီး disk (ကွန်ပျူတာရဲ့ storage) ပေါ်က file ထဲကို ဘယ်တော့မှ မရောက်တာ ဖြစ်နိုင်ပါတယ်။
Overwrite နဲ့ Append ကွာခြားချက်
| Mode | Constructor (object ဖန်တီးချိန် attribute တွေကို စတင် သတ်မှတ်ပေးတဲ့ method) | ဘာဖြစ်သလဲ |
|---|---|---|
| Overwrite | new FileWriter("file.txt") | ရှိပြီးသား content ကို ဖျက်ပြီး အသစ်က စပါတယ် |
| Append (နောက်မှာ ဆက်ထည့်ခြင်း) | new FileWriter("file.txt", true) | ရှိပြီးသား content ရဲ့ အဆုံးမှာ ဆက်ထည့်ပါတယ် |
(Python မှာ overwrite က open("file.txt", "w") ဖြစ်ပြီး append က open("file.txt", "a") ဖြစ်ပါတယ်: mode ကို ပြတဲ့ string (စာသား) က Java ရဲ့ အပို argument (method ကို ခေါ်တဲ့အခါ တကယ် ပေးလိုက်တဲ့ တန်ဖိုး) ရဲ့ အလုပ်ကို လုပ်ပါတယ်။)
// Append mode: adds to end of file
FileWriter writer = new FileWriter("log.txt", true);
writer.write("New entry added.\n");
writer.close();
# Append mode - "a" adds to the end of the file
f = open("log.txt", "a")
f.write("New entry added.\n")
f.close()
လက်ရှိ အခြေအနေ တစ်ခုလုံးကို သိမ်းတဲ့အခါ (ဥပမာ record (အချက်အလက် အများကြီး စုထားတဲ့ ဒေတာ တစ်ခု) အားလုံးကို သိမ်းတဲ့အခါ) overwrite ကို သုံးပါ။ Log (ဖြစ်ခဲ့တာတွေကို အစဉ်လိုက် မှတ်တမ်းတင်ထားတဲ့ file) ဒါမှမဟုတ် မှတ်တမ်း (history) ထဲကို ထပ်ထည့်တဲ့အခါ append ကို သုံးပါ။
BufferedWriter နဲ့ ရေးခြင်း
BufferedWriter (file ထဲ ထိရောက်စွာ ရေးတဲ့ Java class) က ပိုထိရောက်အောင် FileWriter ကို အပြင်ကနေ ထုပ်ထား (wrap) ပြီး newLine() method (သီးခြား အလုပ်တစ်ခု လုပ်ပေးတဲ့ code အပိုင်း) ကိုလည်း ထပ်ပေးပါတယ်။
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
try {
BufferedWriter writer = new BufferedWriter(new FileWriter("results.txt"));
writer.write("Name,Score");
writer.newLine();
writer.write("Alice,85");
writer.newLine();
writer.write("Bob,72");
writer.newLine();
writer.close();
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
}
# Python has no separate BufferedWriter - open() already buffers writes.
# There is no newLine() either: write "\n" yourself (write() adds nothing automatically).
try:
f = open("results.txt", "w")
f.write("Name,Score\n")
f.write("Alice,85\n")
f.write("Bob,72\n")
f.close()
except OSError:
print("Error writing file.")
newLine() က operating system (ကွန်ပျူတာကို စီမံတဲ့ အဓိက software) အတွက် မှန်ကန်တဲ့ line separator (line တွေကို ခြားပေးတဲ့ သင်္ကေတ) ကို ထည့်ပေးပါတယ် (Windows: \r\n၊ macOS/Linux: \n)။ ဒါက "\n" ကို code ထဲမှာ ပုံသေ ရေးထည့်တာ (hardcoding) ထက် operating system အမျိုးမျိုးမှာ ပိုအလုပ်ဖြစ်ပါတယ် (portable)။
try-with-resources (file ကို အလိုအလျောက် ပိတ်ပေးတဲ့ try ပုံစံ)
အသပ်ရပ်ဆုံး နည်းလမ်းပါ: writer ကို အလိုအလျောက် ပိတ်ပေးပါတယ်:
try (BufferedWriter writer = new BufferedWriter(new FileWriter("data.csv"))) {
writer.write("Alice,85");
writer.newLine();
writer.write("Bob,72");
writer.newLine();
} // writer is automatically closed here
(Python မှာလည်း အလားတူ အတိုကောက် နည်းလမ်း with statement (code ထဲက ညွှန်ကြားချက်) ရှိပါတယ်၊ ဒါပေမယ့် IB Python (IB Computer Science သင်ရိုးမှာ သုံးတဲ့ Python ရေးပုံ) က open() နဲ့ close() ကို တိုက်ရိုက် ရေးပြီး သုံးလို့ ဒီ site မှာလည်း အဲဒီအတိုင်း သုံးပါတယ်။)
အဆင့်ဆင့် ရှင်းပြထားတဲ့ ဥပမာများ
ဥပမာ 1: ArrayList (ကြီးလာ၊ သေးသွားနိုင်တဲ့ list) ကို file ထဲ သိမ်းခြင်း
public static void saveNames(ArrayList<String> names, String filename)
throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
for (int i = 0; i < names.size(); i++) {
writer.write(names.get(i));
writer.newLine();
}
writer.close();
}
def save_names(names, filename):
f = open(filename, "w")
for i in range(len(names)):
f.write(names[i] + "\n")
f.close()
ဥပမာ 2: CSV ဒေတာ ရေးခြင်း
ဖွဲ့စည်းပုံရှိတဲ့ ဒေတာကို comma နဲ့ ခြားထားတဲ့ field (record တစ်ခုထဲက အချက်အလက် တစ်ကွက်) တွေနဲ့ သိမ်းပါ။
public static void saveStudents(ArrayList<Student> students, String filename)
throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
for (int i = 0; i < students.size(); i++) {
Student s = students.get(i);
writer.write(s.getName() + "," + s.getGrade());
writer.newLine();
}
writer.close();
}
def save_students(students, filename):
f = open(filename, "w")
for i in range(len(students)):
s = students[i]
f.write(s.get_name() + "," + str(s.get_grade()) + "\n") # str() needed - Python will not join a number onto a string automatically
f.close()
ဥပမာ 3: Log entry တစ်ခု ထပ်ထည့်ခြင်း
public static void logAction(String action, String filename)
throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter(filename, true));
writer.write(action);
writer.newLine();
writer.close();
}
def log_action(action, filename):
f = open(filename, "a") # "a" = append mode
f.write(action + "\n")
f.close()
ဥပမာ 4: ဖတ်ခြင်း၊ တွက်ချက်ခြင်း၊ ရေးခြင်း အဆင့်အားလုံး ပါတဲ့ program အပြည့်အစုံ
အမှတ်တွေကို ဖတ်ပြီး ပျမ်းမျှကို တွက်ကာ summary file (အကျဉ်းချုပ် file) တစ်ခု ရေးပါ။ Input (program ထဲ ထည့်ပေးတဲ့ ဒေတာ) က Reading Files (file ထဲက ဒေတာကို ဖတ်ခြင်း) စာမျက်နှာမှာ သုံးခဲ့တဲ့ file အတိုင်းပါပဲ:
File: students.csv
Alice,85
Bob,72
Charlie,91
import java.util.*;
import java.io.*;
public class ScoreSummary {
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
ArrayList<Integer> scores = new ArrayList<>();
// READ
try (Scanner reader = new Scanner(new File("students.csv"))) {
while (reader.hasNextLine()) {
String[] parts = reader.nextLine().split(",");
names.add(parts[0].trim());
scores.add(Integer.parseInt(parts[1].trim()));
}
} catch (FileNotFoundException e) {
System.out.println("Input file not found.");
return;
}
// PROCESS
int total = 0;
for (int i = 0; i < scores.size(); i++) {
total += scores.get(i);
}
double average = (scores.size() > 0) ? (double) total / scores.size() : 0;
// WRITE
try (BufferedWriter writer = new BufferedWriter(new FileWriter("summary.txt"))) {
writer.write("Student Score Summary");
writer.newLine();
writer.write("=====================");
writer.newLine();
for (int i = 0; i < names.size(); i++) {
writer.write(names.get(i) + ": " + scores.get(i));
writer.newLine();
}
writer.write("---------------------");
writer.newLine();
writer.write("Average: " + average);
writer.newLine();
} catch (IOException e) {
System.out.println("Error writing summary: " + e.getMessage());
}
System.out.println("Summary written to summary.txt");
}
}
# main() is a function here so that "return" can stop the program early,
# exactly like Java's return inside main.
def main():
names = []
scores = []
# READ
try:
f = open("students.csv", "r")
line = f.readline()
while line != "":
parts = line.split(",")
names.append(parts[0].strip())
scores.append(int(parts[1].strip()))
line = f.readline()
f.close()
except FileNotFoundError:
print("Input file not found.")
return # stop - there is nothing to process
# PROCESS
total = 0
for i in range(len(scores)):
total = total + scores[i]
if len(scores) > 0:
average = total / len(scores)
else:
average = 0
# WRITE
try:
f = open("summary.txt", "w")
f.write("Student Score Summary\n")
f.write("=====================\n")
for i in range(len(names)):
f.write(names[i] + ": " + str(scores[i]) + "\n")
f.write("---------------------\n")
f.write("Average: " + str(average) + "\n")
f.close()
except OSError:
print("Error writing summary.")
print("Summary written to summary.txt")
main()
Program က Summary written to summary.txt ကို print ထုတ်ပြီး သူရေးလိုက်တဲ့ file ထဲမှာ ဒါတွေ ပါပါတယ်:
File: summary.txt
Student Score Summary
=====================
Alice: 85
Bob: 72
Charlie: 91
---------------------
Average: 82.66666666666667
ပျမ်းမျှ တန်ဖိုး ရှည်နေတာက Java က double ကို၊ Python က float ကို default (သတ်မှတ်မထားရင် သုံးတဲ့) ပုံစံအတိုင်း print ထုတ်ပုံပါ (နှစ်ခုလုံး ဒသမ ကိန်းတွေပါ)။ ဒသမ နှစ်နေရာအထိ ပြချင်ရင် Java မှာ String.format("%.2f", average) ကို၊ Python မှာ format(average, ".2f") ကို သုံးပါ။
Quick Check (အမြန် စစ်ဆေးမေးခွန်း)
Q1. new FileWriter("data.txt") ကို သုံးရင် ရှိပြီးသား content က ဘာဖြစ်သွားမလဲ။
Q2. File ကို append mode နဲ့ ဘယ်လို ဖွင့်မလဲ။
Q3. writer.newLine() က ဘာလုပ်သလဲ။
Q4. writer.close() ကို ခေါ်ဖို့ မေ့သွားရင် ဘာဖြစ်နိုင်သလဲ။
Q5. File ထဲ ရေးတဲ့အခါ ဘယ် exception ကို catch လုပ်သင့်သလဲ။
Code Completion (code ကွက်လပ် ဖြည့်ခြင်း)
ကျောင်းသား နာမည်တွေနဲ့ grade (အမှတ်) တွေကို CSV (comma နဲ့ ခြားထားတဲ့ စာသား file) file ထဲ သိမ်းပေးတဲ့ method ကို ပြည့်စုံအောင် ဖြည့်ပါ။
ကွက်လပ် ဖြည့်ပါ: ကျောင်းသား တစ်ယောက်စီကို CSV line တစ်ကြောင်းအဖြစ် သိမ်းပါ။
public static void save(ArrayList<Student> students, String filename)
throws IOException {
BufferedWriter writer = new BufferedWriter(new (filename));
for (int i = 0; i < students.size(); i++) {
Student s = students.get(i);
writer.(s.getName() + "," + s.getGrade());
writer.;
}
writer.;
} Spot the Error (အမှား ရှာခြင်း)
ဒီ code က file ထဲကို အမှတ် အသစ် တစ်ခု append လုပ်ရမှာပါ၊ ဒါပေမယ့် အကြိမ်တိုင်း ရှိပြီးသား အားလုံးကို ဖျက်ပစ်ပါတယ်။
အမှား ရှာပါ: ဒီ method run တိုင်း အရင် အမှတ်တွေ ပျောက်သွားပြီး နောက်ဆုံး အမှတ်ပဲ ကျန်ပါတယ်။
Line 2 အတွက် မှန်ကန်တဲ့ ပြင်နည်းကို ရွေးပါ:
Predict the Output (output ကို ကြိုခန့်မှန်းခြင်း)
ကြိုခန့်မှန်းပါ: ဒီ code run ပြီးတဲ့အခါ test.txt file ထဲမှာ ဘာပါမလဲ။
FileWriter writer = new FileWriter("test.txt");
writer.write("Hello");
writer.write("World");
writer.close();
Scanner reader = new Scanner(new File("test.txt"));
System.out.println(reader.nextLine());
reader.close(); Practice Exercises (လေ့ကျင့်ခန်းများ)
Core (အခြေခံ အဆင့်)
-
နာမည် ငါးခု ရေးခြင်း: User ကို နာမည် ငါးခု မေးပါ (keyboard ကနေ Scanner (keyboard ဒါမှမဟုတ် file ကနေ input ဖတ်တဲ့ Java class) နဲ့)၊ ပြီးရင်
names.txtထဲကို line တစ်ကြောင်းမှာ နာမည် တစ်ခုစီ ရေးပါ။ -
Append mode စမ်းသပ်ခြင်း: လေ့ကျင့်ခန်း 1 ကို append mode သုံးအောင် ပြင်ပါ။
names.txtကို အရင် ဖျက်ပြီး append version ကို နှစ်ကြိမ် run ပါ: file ထဲမှာ နာမည် 10 ခု ရှိရပါမယ်။ -
စာလုံးကြီးနဲ့ copy ကူးခြင်း:
input.txtထဲက line အားလုံးကို ဖတ်ပြီး line တစ်ကြောင်းစီကို.toUpperCase()နဲ့ စာလုံးကြီး (uppercase) အဖြစ် ပြောင်းကာoutput.txtထဲကို ရေးပါ။
Extension (တိုးချဲ့ အဆင့်)
-
CSV report:
students.csv(name,score) ကို ဖတ်ပြီး ပျမ်းမျှကို တွက်ကာ ကျောင်းသား တစ်ယောက်စီ၊ သူတို့ရဲ့ အမှတ်နဲ့ ပျမ်းမျှထက် မြင့်လား နိမ့်လား ဆိုတာကို စာရင်းပြုစုထားတဲ့ ပုံစံကျတဲ့ report တစ်ခုကိုreport.txtထဲ ရေးပါ။ -
Timestamp (ရက်စွဲနဲ့ အချိန် မှတ်တမ်း) ပါတဲ့ log:
log.txtထဲကို[YYYY-MM-DD HH:MM:SS] messageပုံစံနဲ့ line တစ်ကြောင်း append လုပ်ပေးတဲ့log(String message)method ကို ရေးပါ။java.time.LocalDateTime.now()ကို သုံးပါ။
Challenge (စိန်ခေါ်မှု အဆင့်)
- File ကို အခြေခံတဲ့ လိပ်စာ စာအုပ် (address book): အဆက်အသွယ် (contact) တွေ (နာမည်၊ ဖုန်း၊ email) ကို CSV file ထဲမှာ သိမ်းတဲ့ program အပြည့်အစုံ တစ်ခု တည်ဆောက်ပါ။ Operation (လုပ်ဆောင်ချက်) လေးမျိုး ပါရပါမယ်: contact တစ်ခု ထည့်ခြင်း (append)၊ contact အားလုံးကို ပြခြင်း (ဖတ်ပြီး ပြခြင်း)၊ နာမည်နဲ့ ရှာခြင်း (ဖတ်ပြီး စစ်ထုတ်ခြင်း) နဲ့ နာမည်နဲ့ ဖျက်ခြင်း (အားလုံးကို ဖတ်ပြီး ကိုက်ညီတဲ့ contact မပါဘဲ ပြန်ရေးခြင်း)။ File က တစ်ခုတည်းသော သိမ်းဆည်းရာ ဖြစ်ရပါမယ်: operation တွေကြားမှာ ဒေတာ ဘာမှ memory (မှတ်ဉာဏ်) ထဲ မထားပါနဲ့။
ဆက်စပ် ခေါင်းစဉ်များ
- အရင် လေ့လာထားရမယ့် ခေါင်းစဉ်: Reading Files (file ထဲက ဒေတာကို ဖတ်ခြင်း): ဖတ်ခြင်းက ရေးခြင်းရဲ့ အတွဲဖက်ပါ
- အရင် လေ့လာထားရမယ့် ခေါင်းစဉ်: Exception Handling (Exception တွေကို ကိုင်တွယ်ခြင်း): IOException တွေအတွက် try/catch
- ဆက်စပ် ခေါင်းစဉ်: ArrayList: ArrayList ထဲက ဒေတာတွေကို file ထဲ သိမ်းခြင်း
- နောက်ထပ် လေ့လာမယ့် ခေါင်းစဉ်: File I/O in Apps (app တွေထဲမှာ file ဖတ်ခြင်း၊ ရေးခြင်း): MVC (app ကို Model၊ View၊ Controller ဆိုပြီး အပိုင်းသုံးပိုင်း ခွဲရေးတဲ့ ပုံစံ) application တွေထဲမှာ ပေါင်းထည့်ထားတဲ့ file I/O