Showing posts with label Java SE : 3 IO. Show all posts
Showing posts with label Java SE : 3 IO. Show all posts

February 15, 2017

I/O Streams

အရင်တစ်ခေါက် File အကြောင်းရေးသားခဲ့စဉ်က File တွေ Directory တွေကို Create လုပ်နိုင်တယ်။ ပြီးတော့လဲ Delete လုပ်နိုင်တယ်။ အမည်ပြောင်းတာတို့လဲ လုပ်နိုင်ခဲ့ပါတယ်။ ဒါပေမဲ့ အဲ့ဒီ File တွေထဲက Data တွေကို Read လုပ်တာတို့ Write လုပ်တာတို့ကို မလုပ်နိုင်ခဲ့ပါဘူး။

File ထဲက Data တွေကို Input Output လုပ်နိုင်ဖို့အတွက် I/O Stream တွေကို အသုံးပြုရမှာ ဖြစ်ပါတယ်။ Java Language မှာ I/O Stream တွေကို အသုံးပြုမည့် Data Type အပေါ်မူတည်ပြီး အမျိုးမျိုးပြင်ဆင်ထားပါတယ်။ ပြီးတော့ I/O Stream တွေကို ရေးသားတဲ့နေရာမှာလဲ Design Pattern တွေကို အသုံးပြုရေးသားထားပါတယ်။ အရင်ဆုံး I/O Stream တွေကို လေ့လာတဲ့နေရာမှာ အသုံးပြုနိုင်တဲ့ I/O Stream တွေနဲ့ အသုံးပြုပုံတွေကို လေ့လာပြီး၊ နောက်ပိုင်းမှ I/O Stream တွေမှာ အသုံးပြုထားတဲ့ Design Patterns တွေကို လေ့လာသွားပါမယ်။


What are Streams?

Stream တွေဟာ Java Program ထဲမှာအသုံးပြုမည့် Input Source တွေနဲ့ Output Destination တွေကိုကိုယ်စားပြုတဲ့ Interface Object တွေဖြစ်ကြပါတယ်။ Source တွေကော Destination တွေပါ ပုံစံအမျိုးမျိုးရှိနိုင်ကြပြီး Input Output လုပ်ကြမည့် Data တွေလဲ​အမျိုးမျိုးဖြစ်နိုင်ပါတယ်။

Input Source လိုပြောတဲ့နေရာမှာ File တစ်ခုလဲဖြစ်နိုင်သလို System Console ကလာတဲ့ Input လဲ ဖြစ်နေနိုင်ပါတယ်။ ဒါမှမဟုတ် အခြားသော Program တစ်ခုခုလဲ ဖြစ်နိုင်ပါတယ်။ ဒီလိုပဲ Output Destination လို့ပြောတဲ့နေရာမှာလဲ File တစ်ခုခု၊ System Console ဒါမှမဟုတ် အခြားသော Program တစ်ခုခုလဲ ဖြစ်နေနိုင်ပါတယ်။ ဒါပေမဲ့ အခြေခံအားဖြင့်တော့ I/O Stream တွေကို Input Stream တွေနဲ့ Output Streams တွေဆိုပြီး သတ်မှတ်ထားပါတယ်။


Input Streams


Java Program ထဲကအသုံးပြုရန် Data များအား Source တစ်နေရာရာမှ ဖတ်ယူနိုင်ဖို့အတွက် Input Stream များကို အသုံးပြုရပါတယ်။ အသုံးပြုလိုတဲ့ Data Type အပေါ်မူတည်ပြီး Streams အမျိုးမျိုးကိုလဲ ပြင်ဆင်ထားပါတယ်။ အသုံးပြုနိုင်တဲ့ Data Type တွေကတော့ bytes, primitive type data, localize character များနဲ့ Object တွေပဲ ဖြစ်ကြပါတယ်။


Output Streams


Java Program ထဲကနေ Destination တစ်ခုဆီကို Data များကို Output လုပ်ချင်တဲ့အခါ Output Stream တွေကို အသုံးပြုနိုင်ပါတယ်။ Destination အနေနဲ့ File တစ်ခုခုဖြစ်နိုင်သလို၊ System Console လဲ ဖြစ်နိုင်သလို အခြားသော Program တစ်ခုခုလဲ ဖြစ်နိုင်ပါတယ်။ ပြီးတော့ byte အနေနဲ့သော်၎င်း၊ primitive data type အနေနဲ့သော်၎င်း၊ localize character များအနေနဲ့သော်၎င်း၊ Object များအနေနဲ့သော်၎င်း Outputလုပ်နိုင်ပါတယ်။

Input Stream တုန်းကလိုပဲ အသုံးပြုလိုတဲ့ Data Type တွေအလိုက် Stream တွေကို ရွေးချယ် အသုံးပြုနိုင်မှာ ဖြစ်ပါတယ်။


Data Types and Streams


Java IO ရဲ့ Stream Class တွေအားလုံးဟာ InputStream နဲ့ OutputStream Class တွေကနေ ဆင်းသက်လာကြတဲ့ Class တွေဖြစ်ပါတယ်။ Input Output အနေနဲ့ အသုံးပြုလိုတဲ့ Data Type အလိုက် Stream တွေကို ခွဲခြားအသုံးပြုနိုင်မှာ ဖြစ်ပါတယ်။

Data Types Input Streams Output Streams
Byte FileInputStream FileOutputStream
Characters FileReader FileWriter
String Line BufferedReader PrintWriter
Primitive Data DataInputStream DataOutputStream
Objects ObjectInputStream ObjectOutputStream


Byte Streams


File တစ်ခုထဲက Data တွေကို Binary Data တွေဖြစ်တဲ့ 8-bit bytes ပုံစံနဲ့ Read Write လုပ်လိုတဲ့အခါ Byte Streams တွေကို အသုံးပြုရမှာ ဖြစ်ပါတယ်။ Byte Stream တွေအားလုံးဟာ InputStream နဲ့ OutputStream Class တွေရဲ့ Sub Class တွေဖြစ်ကြပြီး အသုံးများတာကတော့ FileInputStream နဲ့ FileOutputStream Class တို့ပဲ ဖြစ်ကြပါတယ်။

FileInputStream ကတော့ File တစ်ခုကနေ Byte တွေကို Read လုပ်ချင်တဲ့အခါမှာ အသုံးပြုနိုင်တဲ့ Stream တစ်ခုဖြစ်ပြီး၊ FileInputStream Object ကို တည်ဆောက်ရန် Constructor ၃ မျိုးပြင်ဆင်ထားပါတယ်။

Constructor Description
FileInputStream(File file) Input လုပ်ရမည့် File ကို ကိုယ်စားပြုတဲ့ File Object ကို Argument အနေနဲ့ အသုံးပြုရပါမယ်
FileInputStream(FileDescription fdObj) Input လုပ်မည့် File ကို ဖေါ်ပြပေးနိုင်တဲ့ FileDescriptor Object ကို Argument အနေနဲ့ အသုံးပြုရပါမယ်
FileInputStream(String name) Input လုပ်မည့် File ရဲ့ အမည် String Object ကို Argument အနေနဲ့ အသုံးပြုရပါမယ်

FileInputStream Object ကနေ byte တွေကို 1 byte ချင်း Read လုပ်လိုတဲ့အခါ read() ဆိုတဲ့ Method ကို အသုံးပြုနိုင်မှာ ဖြစ်ပါတယ်။

FileOutputStream ကတော့ File တစ်ခုဆီကို Byte တွေ အနေနဲ့ Output လုပ်ပေးနိုင်တဲ့ Stream Object တစ်ခု ဖြစ်ပါတယ်။ FileOutputStream Object ကို တည်ဆောက်ဖို့အတွက် ပြင်ဆင်ထားတဲ့ Constructor တွေကတော့ အောက်ပါ အတိုင်းဖြစ်ကြပါတယ်။

Constructor Description
FileOutputStream(File file) Output လုပ်ရမည့် File ကို ကိုယ်စားပြုတဲ့ File Object ကို Argument အနေနဲ့ အသုံးပြုရပါမယ်
FileOutputStream(File file, boolean append) Output လုပ်ရမည့် File ကို ကိုယ်စားပြုတဲ့ File Object နဲ့ boolean တန်ဖိုးတစ်ခုကို Argument အနေနဲ့ ပေးရပါမယ်။
boolean ရဲ့ တန်ဖိုးဟာ true ဖြစ်မယ်ဆိုရင် လက်ရှိရှိပြီးသား File မှာ Output လုပ်လာတဲ့ Data တွေကို ဆက်ပြီးထည့်ပေးနိုင်မှာ ဖြစ်ပါတယ်
FileOutputStream(FileDescription fdObj) Output လုပ်မည့် File ကို ဖေါ်ပြပေးနိုင်တဲ့ FileDescriptor Object ကို Argument အနေနဲ့ အသုံးပြုရပါမယ်
FileOutputStream(String name) Output လုပ်မည့် File ရဲ့ အမည် String Object ကို Argument အနေနဲ့ အသုံးပြုရပါမယ်
FileOutputStream(String name, boolean append) Output လုပ်မည့် File ရဲ့ အမည်ကို String Object နဲ့ boolean တန်ဖိုးတစ်ခုကို Argument အနေနဲ့ ပေးရပါမယ်။
boolean ရဲ့ တန်ဖိုးဟာ true ဖြစ်မယ်ဆိုရင် လက်ရှိရှိပြီးသား File မှာ Output လုပ်လာတဲ့ Data တွေကို ဆက်ပြီးထည့်ပေးနိုင်မှာ ဖြစ်ပါတယ်

Output လုပ်လိုတဲ့ Byte Data တွေကို ရေးသားနိုင်ဖို့အတွက် write(int b), write(byte [] b) နဲ့ write(byte [] b, int off, int len) method တို့ကို ပြင်ဆင်ထားပါတယ်။ 1 byte ချင်း Write လုပ်ချင်ရင်တော့ write(int b) ကို အသုံးပြုရမှာ ဖြစ်ပါတယ်။

Stream Object တွေဟာ Resource တွေကို အသုံးပြုနေတဲ့ Object အမျိုးအစား ဖြစ်တဲ့အတွက် အသုံးပြုပြီးတဲ့အခါမှာ ပြန်ပြီး ပိတ်ပေးဖို့လိုအပ်တဲ့အတွက် close() ဆိုတဲ့ Method ကိုလဲ ပြင်ဆင်ပေးထားပါတယ်။ ဒါပေမဲ့ Java SE 7 ရဲ့ ရေးသားပုံအသစ်ဖြစ်တဲ့ try-with-resource ရေးသားပုံနဲ့ ရေးသားမယ်ဆိုရင်တော့ အလိုအလျောက် ပိတ်ပေးနိုင်မှာ ဖြစ်ပါတယ်။
package com.jdc.io.stream.ep1;

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

public class CopyByte {

    public static void main(String[] args) {
        
        try (FileInputStream in = new FileInputStream("from.txt");
                FileOutputStream out = new FileOutputStream("to.txt")){
            
            int i = 0;
            
            while((i = in.read()) != -1) {
                out.write(i);
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

အထက်ပါနမူနာကတော့ from.txt ဆိုတဲ့ File ထဲမှာရှိတဲ့ Data တွေကို 1 byte ချင်း read လုပ်ပြီး to.txt ဆိုတဲ့ဖိုင်ထဲကို 1 byte ချင်း write လုပ်နေတဲ့ နမူနာဖြစ်ပါတယ်။

FileInputStream နဲ့ FileOutputStream Object တွေကို try with resource နဲ့ ရေးသားထားတဲ့အတွက် နောက်ဆုံးမှာ အလိုအလျောက်ပိတ်ပေးသွားမှာ ဖြစ်တယ်။ အဲ့ဒီအတွက် တကူးတက close လုပ်ပေးစရာမလိုတော့ ပါဘူး။ တဖန် while clause ထဲမှာ i = in.read() ဆိုပြီး FileInputStream ကနေ 1 byte ချင်း Read လုပ်နေပါတယ်။ နောက်ဆုံး Read လုပ်စရာမရှိတော့တဲ့အခါ -1 ကို Return ပြန်မှာ ဖြစ်ပြီး While loop ထဲကနေ ထွက်သွားမှာ ဖြစ်ပါတယ်။

While Loop ထဲမှာတော့ Read လုပ်လာတဲ့ တန်ဖိုးကို 1 byte ချင်း FileOutputStream ကို သုံးပြီး write လုပ်ပေးနေပါတယ်။ ဤနည်းအားဖြင့် from.txt ဖိုင်ထဲက Data တွေကို to.txt ဖိုင်ထဲကို 1 byte ချင်း Write လုပ်ပေးသွားနိုင်မှာ ဖြစ်ပါတယ်။


Character Streams

Text File တစ်ခုအတွင်းရှိ Data များကို Character ပုံစံနဲ့ Read / Write လုပ်ချင်ရင် Character Streams များကို အသုံးပြုရမှာ ဖြစ်ပါတယ်။ Character Streams တွေဟာ InputStreamReader နဲ့ OutputStreamWriter တို့ရဲ့ Sub Class တွေ ဖြစ်ကြပြီး FileReader နဲ့ FileWriter တို့ဟာ အသုံးများပါတယ်။

FileReader နဲ့ FileWriter တို့ဟာ Default Encoding နဲ့ Character တွေကို အလွယ်တကူ Read / Write လုပ်နိုင်အောင်ပြင်ဆင်ထားတဲ့ Class တွေဖြစ်ကြပြီး၊ Character Set တို့ကို ကိုယ်တိုင် သတ်မှတ်ပြီး Read / Write လုပ်ချင်ရင်တော့ InputStreamReader နဲ့ OutputStreamWriter တို့ကို အသုံးပြုနိုင်မှာ ဖြစ်ပါတယ်။

FileReader ကို Character များကို Read လုပ်တဲ့နေရာမှာ အသုံးပြုပြီး ရေးသားနိုင်တဲ့ Constructor များကတော့ အောက်ပါ အတိုင်းဖြစ်ကြပါတယ်။

Constructor Description
FileReader(File file) Input လုပ်ရမည့် File ကို ကိုယ်စားပြုတဲ့ File Object ကို Argument အနေနဲ့ အသုံးပြုရပါမယ်
FileReader(FileDescription fdObj) Input လုပ်မည့် File ကို ဖေါ်ပြပေးနိုင်တဲ့ FileDescriptor Object ကို Argument အနေနဲ့ အသုံးပြုရပါမယ်
FileReader(String name) Input လုပ်မည့် File ရဲ့ အမည် String Object ကို Argument အနေနဲ့ အသုံးပြုရပါမယ်

FileWriter ကို Character များကို Write လုပ်တဲ့နေရာမှာ အသုံးပြုပြီး ရေးသားနိုင်တဲ့ Constructor များကတော့ အောက်ပါ အတိုင်းဖြစ်ကြပါတယ်။

Constructor Description
FileWriter(File file) Output လုပ်ရမည့် File ကို ကိုယ်စားပြုတဲ့ File Object ကို Argument အနေနဲ့ အသုံးပြုရပါမယ်
FileWriter(File file, boolean append) Output လုပ်ရမည့် File ကို ကိုယ်စားပြုတဲ့ File Object နဲ့ boolean တန်ဖိုးတစ်ခုကို Argument အနေနဲ့ ပေးရပါမယ်။
boolean ရဲ့ တန်ဖိုးဟာ true ဖြစ်မယ်ဆိုရင် လက်ရှိရှိပြီးသား File မှာ Output လုပ်လာတဲ့ Data တွေကို ဆက်ပြီးထည့်ပေးနိုင်မှာ ဖြစ်ပါတယ်
FileWriter(FileDescription fdObj) Output လုပ်မည့် File ကို ဖေါ်ပြပေးနိုင်တဲ့ FileDescriptor Object ကို Argument အနေနဲ့ အသုံးပြုရပါမယ်
FileWriter(String name) Output လုပ်မည့် File ရဲ့ အမည် String Object ကို Argument အနေနဲ့ အသုံးပြုရပါမယ်
FileWriter(String name, boolean append) Output လုပ်မည့် File ရဲ့ အမည်ကို String Object နဲ့ boolean တန်ဖိုးတစ်ခုကို Argument အနေနဲ့ ပေးရပါမယ်။
boolean ရဲ့ တန်ဖိုးဟာ true ဖြစ်မယ်ဆိုရင် လက်ရှိရှိပြီးသား File မှာ Output လုပ်လာတဲ့ Data တွေကို ဆက်ပြီးထည့်ပေးနိုင်မှာ ဖြစ်ပါတယ်
FileReader နဲ့ FileWriter တို့ရဲ့ အသုံးပြုပုံဟာ အခြေခံအားဖြင့် FileInputStream နဲ့ FileOutputStream တို့နဲ့အတူတူပဲ ဖြစ်ပါတယ်။
package com.jdc.io.stream.ep2;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyChar {
    
    public static void main(String[] args) {
        
        try(FileReader in = new FileReader("from.txt");
                FileWriter out = new FileWriter("out.txt")) {
            
            int c = 0;
            
            while((c = in.read()) != -1) {
                out.write(c);
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }
}

FileReader ကို အသုံးပြုပြီး Text File အတွင်းမှ Character များကို Read လုပ်ရာမှာ read() method ကို အသုံးပြုနိုင်မှာဖြစ်ပါတယ်။ Return Type မှာ int ဖြစ်ပြီး Character တစ်လုံးကို ကိုယ်စားပြုမှာ ဖြစ်ပါတယ်။ နောက်ဆုံး Read လုပ်စရာမရှိတော့တဲ့အခါ -1 ကို Return ပြန်မှာဖြစ်ပါတယ်။

Character စာလုံးများကို Write လုပ်လိုတဲ့အခါ FileWriter Object ရဲ့ write(int char) method ကို အသုံးပြုနိုင်မှာ ဖြစ်ပါတယ်။ Write Method ကို အသုံးပြုပြီး Character တစ်လုံးချင်းစီကို Output လုပ်ပေးနိုင်မှာ ဖြစ်ပါတယ်။

အထက်ပါနမူနာထဲံမှာတော့ from.txt file ထဲမှ Character များကို while statement ဖြင့် တစ်လုံးစီဖတ်ပြီး out.txt file ထဲကို Character တစ်လုံးစီ Output လုပ်ပေးနိုင်မှာ ဖြစ်ပါတယ်။


Line Oriented IO


Character I/O ကို အသုံးပြုတဲ့အခါမှာ Character တစ်လုံးခြင်း Read / Write လုပ်တာထက် ဒီထက်ပိုပြီး ကြီးမားတဲ့ Unit နဲ့ Read / Write လုပ်လေ့ရှိပါတယ်။ အသုံးများတာက စာကြောင်း တစ်ကြောင်းစီကို Read / Write လုပ်တဲ့ပုံစံပဲ ဖြစ်ပါတယ်။ Line တစ်ခုချင်းစီကို Read / Write လုပ်ဖို့အတွက် BufferedReader, BufferedWriter နဲ့ PrintWriter တို့ကို အသုံးပြုနိုင်ပါတယ်။


BufferedReader

BufferedReader တွေဟာ Text File တွေကနေ Character တွေကို သတ်မှတ်ထားတဲ့ Buffered Size အလိုက် Character Array အဖြစ်သော်၎င်း၊ စာကြောင်းတစ်ကြောင်းစီလိုက်သော်၎င်း Read လုပ်နိုင်အောင်ပြင်ဆင်ထားတဲ့ Class တွေ ဖြစ်ပါတယ်။

BufferedReader Class ကို Object ဆောက်နိုင်တဲ့ Constructor တွေကတော့ အောက်ပါ အတိုင်းဖြစ်ပါတယ်။

Constructor Description
BufferedReader(Reader in) Reader Object တစ်ခုကို Argument အနေနဲ့ပေးရပါမယ်။​ Buffer Size ကိုတော့ Default Size အတိုင်း အသုံးပြုသွားမှာ ဖြစ်ပါတယ်။
BufferedReader(Reader in, int size) Reader Object တစ်ခုနဲ့ Buffer Size ကို Argument အနေနဲ့ ပေးပြီး BufferedReader Object တစ်ခုကို တည်ဆောက်နိုင်မှာ ဖြစ်ပါတယ်။ Buffer Size ကို သတ်မှတ်ပြီး အသုံးပြုလိုပါက ဤ Constructor ကို အသုံးပြုရမှာ ဖြစ်ပါတယ်။

package com.jdc.io.stream.ep3;

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

public class LineReader {
    
    public static void main(String[] args) {
        
        try(BufferedReader in = new BufferedReader(new FileReader("line.txt"))) {
            
            String line = null;
            
            while((line = in.readLine()) != null) {
                System.out.println(line);
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

BufferedReader ကနေ စာကြောင်း တစ်ကြောင်းစီ Read လုပ်လိုပါက readLine() method ကို အသုံးပြုနိုင်မှာ ဖြစ်ပါတယ်။ အထက်ပါ နမူနာမှာတော့ in.readLine() ကို အသုံးပြုပြီး line variable မှာ အစားထိုးနေပါတယ်။ ပြီးတော့ While Statement မှာ line ဟာ null မဖြစ်မခြင်း loop ပတ်နေမှာ ဖြစ်ပြီး စာကြောင်းတွေ ဖတ်စရာကုန်သွားရင် null ကို Return လုပ်မှာ ဖြစ်တဲ့အတွက် looping ထဲကနေ ထွက်သွားပါလိမ့်မယ်။

ဒါ့ကြောင့် line.txt ထဲက စာကြောင်းတွေကို အစ စာကြောင်းကနေ တစ်ကြောင်းချင်း ကုန်သွားသည် အထိ Read လုပ်သွားနိုင်မှာ ဖြစ်ပါတယ်။


PrintWriter


Java Program ထဲကနေ Character တွေကို String အနေနဲ့ Write လုပ်လိုတဲ့အခါမှာ PrintWriter ကို အသုံးပြုနိုင်မှာ ဖြစ်ပါတယ်။ PrintWriter ကို အသုံးပြုပြီး String တွေလို ဒီအတိုင်း Write လုပ်နိုင်သလို၊ Format ချပြီးလဲ Write လုပ်နိုင်ပါတယ်။ ထို့အပြင် Locale အလိုက်သတ်မှတ်ပြီးလဲ Format လုပ်နိုင်မှာ ဖြစ်ပါတယ်။ PrintWriter Object ကို တည်ဆောက်နိုင်တဲ့ Constructor တွေကတော့ အောက်ပါ အတိုင်းဖြစ်ကြပါတယ်။

Constructor Description
PrintWriter(File file) Output File ကို သတ်မှတ်ပြီး PrintWriter Object ကို တည်ဆောက်နိုင်မှာ ဖြစ်ပါတယ်။ Auto Flush ကိုတော့ လုပ်ပေးနိုင်မှာ မဟုတ်ပါဘူး
PrintWriter(File file, String csn) Output File နဲ့ Character Set ကို သတ်မှတ်ပြီး PrintWriter Object ကို တည်ဆောက်နိုင်မှာ ဖြစ်ပါတယ်။ Auto Flush ကိုတော့ လုပ်ပေးနိုင်မှာ မဟုတ်ပါဘူး
PrintWriter(OutputStream out) OutputStream ကို သတ်မှတ်ပြီး PrintWriter Object ကို တည်ဆောက်နိုင်မှာ ဖြစ်ပါတယ်။ Auto Flush ကိုတော့ လုပ်ပေးနိုင်မှာ မဟုတ်ပါဘူး
PrintWriter(OutputStream out, boolean autoFlush) OutputStream နဲ့ Auto Flush Mode ကို သတ်မှတ်ပြီး PrintWriter Object ကို တည်ဆောက်နိုင်မှာ ဖြစ်ပါတယ်။
PrintWriter(String fileName) File Name ကို သတ်မှတ်ပြီး PrintWriter Object ကို တည်ဆောက်နိုင်မှာ ဖြစ်ပါတယ်။ Auto Flush ကိုတော့ လုပ်ပေးနိုင်မှာ မဟုတ်ပါဘူး
PrintWriter(String fileName, String csn) File Name နဲ့ Character Set ကို သတ်မှတ်ပြီး PrintWriter Object ကို တည်ဆောက်နိုင်မှာ ဖြစ်ပါတယ်။ Auto Flush ကိုတော့ လုပ်ပေးနိုင်မှာ မဟုတ်ပါဘူး
PrintWriter(Writer out) Writer ကို သတ်မှတ်ပြီး PrintWriter Object ကို တည်ဆောက်နိုင်မှာ ဖြစ်ပါတယ်။ Auto Flush ကိုတော့ လုပ်ပေးနိုင်မှာ မဟုတ်ပါဘူး
PrintWriter(Writer out, boolean autoFlush) Writer နဲ့ Auto Flush Mode ကို သတ်မှတ်ပြီး PrintWriter Object ကို တည်ဆောက်နိုင်မှာ ဖြစ်ပါတယ်။

package com.jdc.io.stream.ep3;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class LineWriter {

    private static final String [] ARRAY = {
            "Hello Java",
            "Hello Java IO",
            "Learn java Programming."
    };
    
    public static void main(String[] args) {
        
        try(PrintWriter out = new PrintWriter(new FileWriter("line.txt"))) {
            
            for (String line : ARRAY) {
                out.println(line);
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

String တွေကို Write လုပ်ဖို့အတွက် print(String str) ဒါမှမဟုတ် write(String str) ကို အသုံးပြုနိုင်ပါတယ်။ ဒါအပြင် Line တွေကို Write လုပ်ဖို့အတွက် println(String str) ကို အသုံးပြုနိုင်ပါတယ်။ Format လုပ်ချင်ရင်တော့ printf(String format, String … param) ကို အသုံးပြုနိုင်မှာ ဖြစ်ပါတယ်။


Data Streams

Primitive Data နဲ့ String တန်ဖိုး တွေကို Read / Write လုပ်ချင်တဲ့အခါ DataInputStream နဲ့  DataOutputStream တို့ကို အသုံးပြုနိုင်ပါတယ်။

Constructor Description
DataOutputStream(OutputStream out) OutputStream Object တစ်ခုကို အသုံးပြုပြီး DataOutputStream ကို တည်ဆောက်ရန် ပြင်ဆင်ထားတဲ့ Constructor ဖြစ်ပါတယ်။
DataInputStream(InputStream in) InputStream Object တစ်ခုကို အသုံးပြုပြီး DataInputStream ကို တည်ဆောက်ရန် ပြင်ဆင်ထားတဲ့ Constructor ဖြစ်ပါတယ်။

အသုံးပြုလိုတဲ့ Data Type အလိုက် Method တွေကိုလဲ ခွဲခြားပြင်ဆင်ထားပါတယ်။

Data Type DataInputStream DataOutputStream
boolean readBoolean() writeBoolean(boolean v)
char readChar() writeChar(int v)
byte readByte() writeByte(int v)
short readShort() writeShort(int v)
int readInt() writeInt(int v)
long readLong() writeLong(long v)
float readFloat() writeFloat(float v)
double readDouble() writeDouble(doble v)
String readUTF() writeUTF(String str)

မိမိအသုံးပြုလိုတဲ့  Data Type အလိုက် သက်ဆိုင်ရာ Method ကို အသုံးပြုပြီး ရေးသားရမှာ ဖြစ်ပါတယ်။


Write Data

package com.jdc.io.stream.ep4;

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

public class DataOutput {
    
    private static final String name = "Aung Aung";
    private static final int age = 20;
    private static final boolean isMan = true;
    
    public static void main(String[] args) {
        
        System.out.println("Starting Output");

        try(DataOutputStream out = new DataOutputStream(new FileOutputStream("data.dat"))) {
            
            out.writeUTF(name);
            out.writeInt(age);
            out.writeBoolean(isMan);
            
            System.out.println("End Output");
        } catch (IOException e) {
            System.out.println("Output Error");
        }
        
    }

}

အထက်ပါနမူနာမှာတော့ name variable ဟာ String ဖြစ်တဲ့အတွက် writeUTF ကို အသုံးပြုပြီး၊ age ဟာ int ဖြစ်တဲ့အတွက် writeInt ကို အသုံးပြုပါတယ်။ တဖန် isMan ဆိုတဲ့ Variable ဟာ boolean type ဖြစ်တဲ့အတွက် writeBoolean ကို အသုံးပြရမှာ ဖြစ်ပါတယ်။


Reading Data

package com.jdc.io.stream.ep4;

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

public class DataInput {

    public static void main(String[] args) {
        
        try(DataInputStream in = new DataInputStream(
                new FileInputStream("data.dat"))) {
            
            System.out.println("Name : " + in.readUTF());
            System.out.println("Age  : " + in.readInt());
            System.out.println("Male : " + in.readBoolean());
            
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }
}

အထက်ပါ နမူနာကတော့ DataOutput ဖြင့် Write လုပ်ထားတဲ့ data.dat file ထဲက Data တွေကို ပြန်ပြီး Read လုပ်နေတာဖြစ်ပါတယ်။ String Data တွေကို readUTF ကိုအသုံးပြုပြီး၊ int ကိုတော့ readInt ကို အသုံးပြုပါတယ်။ တဖန် boolean ကိုတော့ readBoolean method ကို အသုံးပြုပါတယ်။


Serialization

အရှေ့တွင်ဖေါ်ပြခဲ့သလို Java ဘာသာရပ်တွင် Byte, Character, Primitive Data များနှင့် String များကို Read / Write လုပ်နိုင်တဲ့အပြင် Object တွေကိုလဲ Object အတိုင်း Read / Write လုပ်နိုင်ပါတယ်။

Java ဘာသာရပ်မှာ JVM Memory အပေါ်မှာရှိတဲ့ Object တွေကို အခြား တစ်နေနေရာကို ပို့ပေးလိုက်ခြင်းကို Serialize လုပ်တယ်လို့ခေါ်ပါတယ်။ တဖန် တစ်ခြားတစ်နေနေရာကနေလာတဲ့ Serialized လုပ်ထားတဲ့ Data တွေကနေ JVM Memory အပေါ်ကို ပြန်ပြီး Object အဖြစ်ပြန်ပြောင်းတာကိုတော့ Deserialize လုပ်တယ်လို့ခေါ်ပါတယ်။ Deseiralize လုပ်တယ်ဆိုတာကလဲ Serialize လုပ်ထားတဲ့ Data များကိုသာ ပြုလုပ်နိုင်မှာ ဖြစ်ပါတယ်။

နမူနာအားဖြင့် Program ထဲမှာ သုံးနေတဲ့ Java Object တွေကို File တစ်ခုခုမှာ သွားသိမ်းတာတို့၊ Internet ကိုဖြတ်ပြီး တစ်ခြားတစ်နေနေရာကိုပို့ပေးတာတို့ဟာ Serialize လုပ်တာဖြစ်ကြပါတယ်။ Server အပေါ်မှာရှိတဲ့ Object တွေကို Session ပေါ်မှာ သုံးနေတယ်ဆိုတာကလဲ Serialize လုပ်နေတာပဲ ဖြစ်ပါတယ်။

ဒါဖြင့် ဘယ်လို Object တွေကို Serialize လုပ်လို့ရတာလဲ။ Primitive Data Type တွေ၊ Serializable Interface ကို Implement လုပ်ထားတဲ့ Object တွေနဲ့ Serializable Object တွေရဲ့ Collection တွေ ဆိုရင် Serialize လုပ်လို့ရမှာ ဖြစ်ပါတယ်။

Object တစ်ခုကို Serialize လုပ်တဲ့အခါမှာ Object ရဲ့ State တွေဖြစ်ကြတဲ့ Instance Variable တွေကိုသာ Serialize လုပ်သွားမှာ ဖြစ်ပါတယ်။ ဒါ့ကြောင့် Serialize လုပ်မည့် Object ရဲ့ Instance Variable တွေဟာလဲ Serializable ဖြစ်ဖို့လိုအပ်ပါတယ်။ တကယ်လို့ Serialize မလုပ်ချင်တဲ့ Instance Variable တွေဆိုရင် transient modifier ကို ရေးသားပြီး ဖေါ်ပြနိုင်ပါတယ်။ Instance Variable တွေရှေ့မှာ transient ကို ရေးသားထားရင် အဲ့ဒီ Field ကို Serialize လုပ်မှာ မဟုတ်တော့ပါဘူး။
package com.jdc.io.stream.ep5;

import java.io.Serializable;

public class Employee implements Serializable{

    private static final long serialVersionUID = 1L;

    private int id;
    private String name;
    private String phone;
  
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
}


Serial Version UID

Serializable Object တစ်ခုကို Serialize လုပ်ပြီး ပြန်ပြီး Deserialize လုပ်တဲ့အခါ Serial Version UID ကို အသုံးပြုပြီး Class ရဲ့ Version မှန်မမှန်ကို ပြန်ပြီး စစ်ဆေးလေ့ရှိပါတယ်။ Serial Version UID ကို ရေးသားရာမှာ static final long serialVersionUID ဆိုတဲ့ပုံစံနဲ့ ရေးသားပေးရပါတယ်။ Access Modifier ကိုတော့ နှစ်သက်ရာ ရေးသားအသုံးပြုနိုင်ပါတယ်။

Serialize လုပ်တဲ့အခါမှာ Serial Version UID ဟာ Static Variable ဖြစ်ပေမဲ့ ခြွင်းချက်အနေနဲ့ Serialize အလုပ်ခံရမှာ ဖြစ်ပါတယ်။ Deserialize လုပ်တဲ့အခါမှာ လက်ရှိ Class နဲ့ Deserialize လုပ်မည့် Object ရဲ့ Serial Version UID ကို တိုက်စစ်ပြီး မှန်ကန်မှသာ Serialize လုပ်ပေးမှာ ဖြစ်ပါတယ်။ တကယ်လို့ Version နှစ်ခုမတူညီခဲ့ပါက InvalidClassException ကို ဖြစ်ပေါ်စေမှာ ဖြစ်ပါတယ်။

တကယ်လို့ Serializable Class တစ်ခုမှာ Serial Version UID ကို မရေးထားဖူးဆိုရင် Serialize လုပ်တဲ့အခါမှာ JVM ကနေ နှစ်သက်ရာ ID တစ်ခုကို Generate လုပ်ပေးမှာ ဖြစ်ပါတယ်။

ဒါပေမဲ့ Serial Version UID Calculation ဟာ Compiler Implementation အပေါ်မူတည်ပြီး ပြောင်းလဲတတ်တဲ့အတွက် Serial Version UID ကို Class အတွင်းမှာ မဖြစ်မနေရေးသားသင့်ပါတယ်။


Writing Objects (Serialization)

Java Program ထဲကနေ Memory အပေါ်မှာရှိတဲ့ Serializable Object တွေနဲ့ Serializable Object ရဲ့ Collection တွေကို Serialize လုပ်လိုတဲ့အခါမှာ ObjectOutputStream ကို အသုံးပြုနိုင်မှာ ဖြစ်ပါတယ်။ ObjectOutputStream ကို အသုံးပြုပြီး Primitive Data တွေနဲ့ Serializable Object Graphs တွေကို Serialize လုပ်ပေးနိုင်မှာ ဖြစ်ပါတယ်။

Object တွေကို Serialize လုပ်တဲ့နေရာမှာလဲ File တွေမှာလဲ Serialize လုပ်နိုင်သလို Network ကို အသုံးပြုတဲ့ Socket Stream တွေနဲ့လဲ တွဲဖက် အသုံးပြုနိုင်မှာ ဖြစ်ပါတယ်။ ObjectOutputStream ရဲ့ Constructor တွေကတော့ အောက်ပါအတိုင်း ဖြစ်ကြပါတယ်။

Constructor Description
ObjectOutputStream() ObjectOutputStream ရဲ့ Sub Class တွေအတွက် ပြင်ဆင်ထားပေးတဲ့ Constructor ဖြစ်ပါတယ်။
ObjectOutputStream(OutputStream out) OutputStream Object တစ်ခုကို အသုံးပြုပြီး ObjectOuputStream ကို တည်ဆောက်ရန် ပြင်ဆင်ထားတဲ့ Constructor ဖြစ်ပါတယ်။

package com.jdc.io.stream.ep5;

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

public class ObjectWriteTest {

    public static void main(String[] args) {
        Employee e = new Employee();
        e.setId(1);
        e.setName("Aung Aung");
        e.setPhone("09788986677");
        
        try(ObjectOutputStream out = new ObjectOutputStream(
                new FileOutputStream("employee.obj"))) {
            out.writeObject(e);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }
}
အထက်ပါနမူနာအတိုင်း JVM Memory အပေါ်မှာရှိတဲ့ Object တွေကို Serialize လုပ်လိုပါက writeObject(Object obj) method ကို အသုံးပြုနိုင်မှာ ဖြစ်ပါတယ်။


Reading Objects (Deserialization)

ObjectOutputStream ကို အသုံးပြုပြီး Serialize လုပ်ထားတဲ့ Primitive Data တွေနဲ့ Object တွေကို Deserialize လုပ်လိုတဲ့အခါ ObjectInputStream ကို အသုံးပြုရမှာ ဖြစ်ပါတယ်။

File ထဲမှာရှိတဲ့ Data တွေကို Deserialize လုပ်တဲ့အခါမျိုးမှာ ObjectInputStream ဟာ FileInputStream ကို အသုံးပြုပါတယ်။ ဒါကြောင့် File ထဲက Data တွေကို Read လုပ်လိုတဲ့အခါမျိုးမှာ InputStream Parameter နေရာမှာ FileInputStream Object ကို အသုံးပြုရမှာ ဖြစ်ပါတယ်။

တဖန် Remote System တစ်ခုကနေ Data တွေကို ရယူတဲ့အခါမျိုးမှာတော့ Socket Streams ကို အသုံးပြုပြီး Data တွေကို Deserialize လုပ်နိုင်ပါတယ်။

Constructor Description
ObjectInputStream() ObjectInputStream ရဲ့ Sub Class တွေအတွက် ပြင်ဆင်ထားပေးတဲ့ Constructor ဖြစ်ပါတယ်။
ObjectInputStream(InputStream in) OutputStream Object တစ်ခုကို အသုံးပြုပြီး ObjectOuputStream ကို တည်ဆောက်ရန် ပြင်ဆင်ထားတဲ့ Constructor ဖြစ်ပါတယ်။

package com.jdc.io.stream.ep5;

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

public class ObjectReadTest {

    public static void main(String[] args) {
        
        try(ObjectInputStream in = new ObjectInputStream(
                new FileInputStream("employee.obj"))) {
            
            Employee e = (Employee) in.readObject();
            
            System.out.println(e.getName());
            
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

ယခင် နမူနာဖြင့် Serialize လုပ်ထားတဲ့ Employee Object ကို Deserialize လုပ်လိုတဲ့အခါ အထက်ပါအတိုင်း ObjectInputStream ကို အသုံးပြုပြီး ရေးသားနိုင်ပါတယ်။ အထက်ပါအတိုင်း in.readObject() method ရဲ့ Return Type ဟာ Object ဖြစ်နေတဲ့အတွက် Employee အဖြစ်ပြန်ပြီး Cast လုပ်ပေးဖို့လိုအပ်ပါတယ်။

ဆက်ပါဦးမယ်
မင်းလွင်

January 3, 2017

File

Java IO API ဟာ JDK version 1.0 ကထဲကပါဝင်လာခဲ့တဲ့ Input Output ကို လုပ်ဆောင်ဖို့အတွက် API တစ်ခုဖြစ်ပါတယ်။ File System ထဲမှာ ရှိတဲ့ File တွေ Directory တွေရဲ့ Path ကို ကိုယ်စားပြုဖို့အတွက် java.io.File Class ကို ပြင်ဆင်ထားပါတယ်။ File Class ဟာ Serializable နဲ့ Comparable<File> ကို Implement လုပ်ထားတဲ့ Class တစ်ခုဖြစ်ပါတယ်။


How To Create File Object


အရင်ဦးဆုံး File Object တစ်ခုကို ဘယ်လို တည်ဆောက်မလဲ ဆိုတာကနေစပြီး လေ့လာကြည့်ကြရအောင်။ File Object ကို တည်ဆောက်ဖို့ အတွက် Constructors တွေကို ပြင်ဆင်ထားပါတယ်။ File Object ကို တည်ဆောက်တဲ့ နေရာမှာ လက်ရှိရှိပြီးသား File Directory တွေကိုကိုယ်စားပြုတဲ့ Object တွေကိုလဲ တည်ဆောက်နိုင်သလို၊ လက်တွေ့မှာ မရှိသော်လည်း Virtually တည်ဆောက်ထားလို့ရပါတယ်။ File Object ကို တည်ဆောက်ပြီး လိုအပ်လာတဲ့အခါကျမှ Create လုပ်လို့လဲ ရနိုင်ပါတယ်။ ဒါဆို File Class ထဲမှာပါတဲ့ Constructors တွေကို လေ့လာကြည့်ကြရအောင်။

Constructor Description
File(File parent, String child) Parent ဖြစ်တဲ့ File Object တစ်ခုနဲ့ Child Path Name တို့ဖြင့် File Object ကို တည်ဆောက်နိုင်တဲ့ Constructor ဖြစ်ပါတယ်
File(String pathname) File Directory ရဲ့ Path String ကနေ File Object ကို တည်ဆောက်နိုင်တဲ့ Constructor ဖြစ်ပါတယ်။ Path အနေနဲ့ Absolute Path ကော Relative Path ကို ပါ အသုံးပြုနိုင်မှာ ဖြစ်ပါတယ်
File(String parent, String child) File Directory တို့ရှိနေတဲ့ Directory Path နဲ့ File Name တို့ကနေ File Object ကို တည်ဆောက်နိုင်တဲ့ Constructor ဖြစ်ပါတယ်။
File(URI uri) File Directory တို့ကိုဖေါ်ပြနိုင်တဲ့ URI Object ကနေတဆင့် File Object ကိုတည်ဆောက်နိုင်တဲ့ Costructor ဖြစ်ပါတယ်။

File Class ရဲ့ Constructor တွေကို လေ့လာကြည့်ရင် File တစ်ခုကို တည်ဆောက်ဖို့အတွက်က အဲ့ဒီ File ရဲ့ Path ကို ဖေါ်ပြပေးနိုင်ဖို့လိုတာကို တွေ့ရပါမယ်။ အဲ့ဒီ Path ကို ဖေါ်ပြတဲ့နေရာမှာ Absoulte Path နဲ့လည်း ဖေါ်ပြနိုင်သလို Relative Path နဲ့ လည်းဖေါ်ပြနိုင်မှာ ဖြစ်ပါတယ်။
import java.io.*;

public class FileCreation {
    
    public static void main(String [] args) {

        // File Path
        File file1 = new File("file1");

        // Parent File and File Path
        File file2 = new File(file1, "file2.txt");

        // Parent File Path and File Path
        File file3 = new File("file1", "file3.txt");

        // URI
        URI uri = new URI("c:\\file1\\file4.txt");
        File file4 = new File(uri);
    }
}


Create & Delete File

File Object ကနေ File Directory တွေကို တည်ဆောက်နိုင်ဖို့၊ ပြီးတော့ ရှိပြီးသား File တွေကို ဖျက်နိုင်ဖို့အတွက် အောက်ပါ Methods တွေကို အသုံးပြုနိုင်ပါတယ်။

Method Return Type & Description
createNewFile() boolean

File Object မှာ သတ်မှတ်ထားခဲ့တဲ့ Abstract Path Name ဖြင့် Empty New File တစ်ခုကို တည်ဆောက်ပေးပါလိမ့်မယ်။ တကယ်လို့ Path အတိုင်း File ဟာရှိနေမယ်ဆိုရင် ဆောက်ပေးနိုင်မှာ မဟုတ်ပါဘူး။ File ကို တည်ဆောက်နိုင်ခဲ့ရင် true ကို Return လုပ်မှာ ဖြစ်ပြီး မဆောက်နိုင်ခဲ့ပါက false ကို Return ပြန်မှာ ဖြစ်ပါတယ်။
IOException ကို ဖြစ်ပေါ်စေနိုင်တဲ့အတွက် Handle လုပ်ပေးဖို့လိုအပ်ပါတယ်။
mkdir() boolean

File Object မှာ သတ်မှတ်ထားတဲ့ Abstract Path Name ဖြင့် Directory ကို တည်ဆောက်ပေးမှာ ဖြစ်ပါတယ်။ တည်ဆောက်နိုင်ခဲ့ရင် true ကို Return ပြန်မှာ ဖြစ်ပြီး မတည်ဆောက်နိုင်ခဲ့ပါက false ကို Return ပြန်မှာ ဖြစ်ပါတယ်
mkdirs() boolean

File Object မှာ သတ်မှတ်ထားတဲ့ Abstract Path Name ဖြင့် Directory ကို တည်ဆောက်ပေးမှာ ဖြစ်ပါတယ်။ Child Directories တွေပါလာရင်တော့ ဒီ Method ကို အသုံးပြုရမှာ ဖြစ်ပါတယ်။ တည်ဆောက်နိုင်ခဲ့ရင် true ကို Return ပြန်မှာ ဖြစ်ပြီး မတည်ဆောက်နိုင်ခဲ့ပါက false ကို Return ပြန်မှာ ဖြစ်ပါတယ်
delete() boolean

File Object ဖြင့် ကိုယ်စားပြုသော File Directory ကို delete လုပ်လိုတဲ့အခါမှာ အသုံးပြုနိုင်ပါတယ်။ အောင်မြင်စွာ ပြီးဆုံးပါက true ကို Return ပြန်မှာ ဖြစ်ပြီး မဖျက်နိုင်ခဲ့ပါက false ကို Return ပြန်မှာ ဖြစ်ပါတယ်။
deleteOnExit() void

File Object ကို JVM ကနေ Application ကို Run တာပြီးတဲ့ အချိန်မှာ Delete လုပ်ပေးမှာ ဖြစ်ပါတယ်။ Return Type တော့မရှိပါဘူး။

import java.io.*;

public class FileTest {

    public static void main(String[] args) throws IOException{
        
        File file = new File("Test.txt");
        boolean result1 = file.createNewFile();

        System.out.println(result1 ? "Success" : "Fails");

        File dir1 = new File("outer");
        File dir2 = new File(dir1, "inner");

        dir1.mkdirs();

        boolean result2 = dir1.delete();
        System.out.println(result2 ? "Success" : "Fails");
    }
}



About Path Information

Path လမ်းကြောင်းနဲ့ပတ်သက်ပြီး အောက်ပါ Method များကို အသုံးပြုနိုင်ပါတယ်။

Method Return Type Description
getAbsoluteFile() File

Absolute Path ပုံစံနဲ့ တည်ဆောက်ထားတဲ့ File Object ကို ရရှိမှာ ဖြစ်ပါတယ်။
getAbsolutePath() String

File Object ရဲ့ Absolute Path ကို ရရှိမှာ ဖြစ်ပါတယ်
getCanonicalFile() File

Canonical ပုံစံဖြင့်တည်ဆောက်ထားတဲ့ File Object ကို ရရှိမှာ ဖြစ်ပါတယ်
getCanonicalPath() String

Absolute and Unique ဖြစ်တဲ့ Canonical File Path ကို ရရှိမှာ ဖြစ်ပါတယ်
getName() String

File Name ကို ရရှိမှာ ဖြစ်ပါတယ်။
getParent() String

Parent Directory ရဲ့ Name ကို ရရှိမှာ ဖြစ်ပါတယ်။ တကယ်လို့ သတ်မှတ်ထားခြင်း မရှိပါက null ကို ပြန်ရမှာ ဖြစ်ပါတယ်။
getParentFile() File

Parent Directory ရဲ့ File Object ကို ပြန်ရမှာဖြစ်ပါတယ်။ သတ်မှတ်ထားခြင်းမရှိပါက null ကို ပြန်ရမှာ ဖြစ်ပါတယ်။
getPath() String

Absolute Path Name ကို Return အနေနဲ့ ပြန်လည် ရရှိမှာ ဖြစ်ပါတယ်။
isAbsolute() boolean

File Object ကို သတ်မှတ်ထားတဲ့ File Name ဟာ Absolute Path ဟုတ်မဟုတ်ကို စစ်ဆေးနိုင်တဲ့ Method ဖြစ်ပါတယ်။
renameTo(File dest) boolean

လက်ရှိ File Object ကို Parameter ထဲက File အဖြစ်ပြောင်းလဲနိုင်တဲ့ Method တစ်ခုဖြစ်ပါတယ်။ File အမည် ပြောင်းတဲ့ နေရာမှာလဲ အသုံးဝင်သလို File တစ်ခုကနေ တစ်ခုကို ပြောင်းရွှေ့တဲ့နေရာမှာလဲ အသုံးဝင်ပါတယ်။

import java.io.*;

public class MoveFile {

    public static void main(String[] args) throws Exception {
        File f1 = new File("file1.txt");
        f1.createNewFile();

        File f2 = new File("dir");
        f2.mkdir();

        File f3 = new File(f2, "file2.txt");
        f1.renameTo(f3);
    }

}


Using Metadata


Method Return Type Description
isDirectory() boolean

Directory တစ်ခု ဟုတ်မဟုတ်ကို သိရှိစေနိုင်သော Method ဖြစ်ပါတယ်
isFile() boolean

File တစ်ခု ဟုတ်မဟုတ်ကို သိရှိစေနိုင်သော Method ဖြစ်ပါတယ်
isHidden() boolean

Hidden File တစ်ခု ဟုတ်မဟုတ်ကို သိရှိစေနိုင်သော Method ဖြစ်ပါတယ်
lastModified() long

နောက်ဆုံး Modified လုပ်သွားသော အချိန်ကို သိရှိစေနိုင်သော Method ဖြစ်ပါတယ်
getTotalSpace() long

File Name နဲ့သတ်မှတ်ထားတဲ့ Partition ရဲ့ ပမာဏကို သိရှိစေနိုင်သော Method ဖြစ်ပါတယ်
getFreeSpace() long

File Name နဲ့သတ်မှတ်ထားတဲ့ Partition ထဲမှာရှိတဲ့ Free Space ကို သိရှိစေနိုင်သော Method ဖြစ်ပါတယ်
getUsableSpace() long

File Name နဲ့သတ်မှတ်ထားတဲ့ Partition ထဲမှာရှိတဲ့ အသုံးပြုနိုင်သော ပမာဏကို သိရှိစေနိုင်သော Method ဖြစ်ပါတယ်
setLastModified(long time) boolean

နောက်ဆုံး Modified လုပ်တဲ့အချိန်ကို သတ်မှတ်ပေးနိုင်သော Method ဖြစ်ပါတယ်
setExcutable(boolean executable) boolean

Program တစ်ခုအနေနဲ့ Run လို့ရမရကို သတ်မှတ်ပေးနိုင်သော Method ဖြစ်ပါတယ်
setExcutable(boolean executable, boolean ownerOnly) boolean

Program တစ်ခုအနေနဲ့ Run လို့ရမရကို File Owner တစ်ယောက်ထဲ လုပ်လို့ရတာလား ဆိုတဲ့ အချက်ကိုပါ သတ်မှတ်ပေးနိုင်သော Method ဖြစ်ပါတယ်
setReadable(boolean readable) boolean

File ကို Read လုပ်လို့ရမရကိုသတ်မှတ်ပေးနိုင်သော Methodဖြစ်ပါတယ်
setReadable(boolean readable, boolean ownerOnly) boolean

File ကို Read လုပ်လို့ရမရကို File Owner တစ်ယောက်ထဲ လုပ်လို့ရတာလား ဆိုတဲ့ အချက်ကိုပါ သတ်မှတ်ပေးနိုင်သော Method ဖြစ်ပါတယ်
setReadOnly() boolean

Read Only File အဖြစ်သတ်မှတ်ပေးနိုင်သော Method ဖြစ်ပါတယ်။
setWritable(boolean writable) boolean

Write လုပ်လို့ရမရကို သတ်မှတ်ပေးနိုင်သော Method ဖြစ်ပါတယ်။
setWritable(boolean writable, boolean ownerOnly) boolean
Write လုပ်လို့ရမရကို File Owner တစ်ယောက်ထဲ လုပ်လို့ရတာလား ဆိုတဲ့ အချက်ကိုပါ သတ်မှတ်ပေးနိုင်သော Method ဖြစ်ပါတယ်


Methods for Directory

အောက်ပါ  Method တွေကတော့ File Object ဟာ Directory တစ်ခုဖြစ်မှသာ အသုံးပြုနိုင်မည့် Method တွေ ဖြစ်ပါတယ်။

Method Return Type Description
list() String[]

လက်ရှိ Directory အောက်မှာရှိတဲ့ File တွေ Directory တွေရဲ့ အမည်ကို String [] အနေနဲ့ ပြန်လည် ရရှိမှာ ဖြစ်ပါတယ်။
list(FileNameFilter filter) String[]

လက်ရှိ Directory အောက်မှာရှိတဲ့ File တွေရဲ့ Directory တွေရဲ့ အမည်ကို FileNameFilter Interface Object ကို သုံးပြီး Filter လုပ်ပြီး ပြန်လည်ရရှိနိုင်မှာ ဖြစ်ပါတယ်
listFiles() File[]

လက်ရှိ Directory အောက်မှာရှိတဲ့ File တွေ Directory တွေကို File[] အနေနဲ့ ပြန်လည် ရရှိမှာ ဖြစ်ပါတယ်။
listFiles(FileNameFilter filter) File[]

လက်ရှိ Directory အောက်မှာရှိတဲ့ File တွေ Directory တွေကို FileNameFilter Interface Object ကို သုံးပြီး Filter လုပ်ပြီး ပြန်လည်ရရှိနိုင်မှာ ဖြစ်ပါတယ်
listFiles(FileFilter filter) File[]

လက်ရှိ Directory အောက်မှာရှိတဲ့ File တွေ Directory တွေကို FileFilter Interface Object ကို သုံးပြီး Filter လုပ်ပြီး ပြန်လည်ရရှိနိုင်မှာ ဖြစ်ပါတယ်

ဒီတစ်ခေါက်တော့ Directory ထဲမှာရှိတဲ့ File တွေကို နာမည်တစ်ခုနဲ့ ရှာပြီး ဖျက်တဲ့ နမူနာတစ်ခု ရေးကြည့်ပါမယ်။ Maven ကို သုံးပြီး Library တွေကို Download လုပ်တဲ့အခါမှာ Connection မကောင်းရင် LastUpdate ဆိုတဲ့နာမည်နဲ့ File တွေကို ချန်ထားပြီး ရပ်သွားတတ်ပါတယ်။ အဲ့ဒီ File တွေကို ရှာပြီး Delete လုပ်ပေးနိုင်တဲ့ နမူနာ တစ်ခုကို ရေးကြည့်ပါမယ်။
import java.io.File;

public class MavenDelete {
    
    public static void main(String[] args) {
        String userHome = System.getProperty("user.home");
        File maven = new File(userHome, ".m2");
        File mavenRepo = new File(maven, "repository");
        deleteFiles(mavenRepo);
    }
    
    static void deleteFiles(File file) {
        if(file.isDirectory()) {
            File [] files = file.listFiles(f -> f.isDirectory() || f.getName().endsWith("lastUpdate"));
            for(File f : files) {
                deleteFiles(f);
            }
        } else {
            file.delete();
        }
    }
}

အထက်ပါ နမူနာထဲမှာတော့ mavenRepo file ကို deleteFiles method ကို သုံးပြီး ဖျက်ခိုင်းပါတယ်။ တကယ်လို့ file Object ဟာ directory ဖြစ်ရင် အဲ့ဒီ​ Directory ထဲက Directory တွေနဲ့ lastUpdate နဲ့ ဆုံးရင် ရယူလာအောင် FileFilter နေရာကို Lambda Expression နဲ့ Filter လုပ်ထားပါတယ်။ရလာတဲ့ File တွေကို Loop ပတ်ပြီး
deleteFile ကို ပြန်ခေါ်ခိုင်းပါတယ်။

တကယ်လို့ Directory ဆိုရင် အောက်မှာ ရှိတဲ့ File တွေကို ရှာပြီး deleteFile ကို ပြန်ခေါ်ပါလိမ့်မယ်။ Directory မဟုတ်ပဲ File တွေဖြစ်နေလို့ကတော့ lastUpdate နဲ့ ဆုံးနေမှာ ဖြစ်တဲ့အတွက် delete လုပ်သွားပါမယ်။


Switch Other Types


Method Return Type Description
toPath() Path

Java NiO2 ရဲ့ Path Object အဖြစ်ပြောင်းပေးနိုင်တဲ့ Method ဖြစ်ပါတယ်
toStirng() String

File Object ရဲ့ Path Name ကို ရရှိနိုင်မှာ ဖြစ်ပါတယ်။ getPath method နှင့် ရလဒ်ခြင်း အတူတူဖြစ်ပါတယ်
toURI() URI

File Path Name ကို ကိုယ်စားပြုသော URI Object ကို ပြန်လည်ရရှိမှာ ဖြစ်ပါတယ်

File Object ဟာ Java IO ကို အသုံးပြုရာမှာ မရှိမဖြစ်လိုအပ်သော Object တစ်ခုဖြစ်ပါတယ်။ လက်ရှိ File တွေ Directory တွေရဲ့ Abstract Path Name ကို ကိုယ်စားပြုတဲ့ Object တစ်ခုဖြစ်ပါတယ်။ File Object တစ်ခုကို ဘယ်လို Create လုပ်မယ်။ File တွေ Directory တွေကို ဘယ်လို တည်ဆောက်မယ်၊ ပြီးရင် Delete လုပ်မယ်။ Directory ထဲမှာရှိတဲ့ File တွေကို ဘယ်လို ရှာဖွေမယ်ဆိုတာကို သိရှိထားအောင် လေ့လာထားဖို့ လိုအပ်ပါမယ်။

ဆက်ပါဦးမယ်
မင်းလွင်

December 30, 2016

About Java IO

Java အကြောင်းကိုလေ့လာမယ်ဆိုရင် Java Programming ရေးသားပုံရေးသားနည်းတွေ စည်းကမ်းတွေ၊ ပြီးတော OOP ဆိုတဲ့ Conceptတွေ၊ Version အလိုက် အသစ်ပါဝင်တဲ့ Features တွေ အပြင် အသုံးများတဲ့ API တွေကို လေ့လာဖို့လိုအပ်ပါတယ်။ Java IO ဆိုတာကလဲ Java Programming ကို လေ့လာရာမှာ မရှိမဖြစ်လိုအပ်တဲ့ Essential API တစ်ခုဖြစ်ပါတယ်။

ကိုယ့် Blog ကို ကိုယ်ပြန်ကြည့်တဲ့အခါမှာ IO အကြောင်း ရေးမထားပဲ NIO2 ကိုတော့ ရေးထားတယ်။ ဒါ့ကြောင့် IO ကို ပြန်ရေးပါမယ်။ IO ကို နားလည်ပြီးမှ NIO2 ကို လုပ်တာကောင်းပါတယ်။ ဒါ့ကြောင့် Java IO ကို ပြန်ပြီး ရေးပါမယ်။

API ဆိုတာ ကျွန်တော်တို့ အစဉ်သင့် အသုံးပြုနိုင်အောင် ကြိုတင်ရေးသားထားတဲ့ Class Library တွေသာ ဖြစ်ကြတယ်။ ဒါ့ကြောင့် API ကို လေ့လာမယ်ဆီုရင် အဓိက ဘာတွေကို ပံ့ပိုးပေးမှာလဲ၊ အခြေခံသိထားသင့်တဲ့ Interface တွေက ဘာတွေလဲ၊ ပြီးတော့ အသေးစိတ်ဘယ်လိုလုပ်ကြမလဲ​ဆိုတာကို လေ့လာတာက အလွယ်တကူအသုံးပြုနိုင်မှာ ဖြစ်ပါတယ်။

နောက်ကွယ်က ဘာတွေ ဖြစ်နေတယ် ဘာတွေလုပ်နေတယ်ဆိုတာကို သိစရာ မလိုပါဘူး။ ဘာလို့လဲဆိုတော့ ကားမောင်းချင်ရင် ကားကို ဘယ်လို မောင်းရတယ်သိရင်ရပြီ မဟုတ်လား။ ကားမောင်းနေတဲ့အချိန်မှာ နောက်ကွယ်မှာ အင်ဂျင်ထဲမှာ တစ်ဆင့်ချင်း ဘယ်လို လုပ်သွားတယ်ဆိုတာ ကားမောင်းသူအတွက် သိဖို့လိုအပ်လို့လား။

တစ်ချို့ကပြောမယ်။ API တွေကို သိချင်ရင် နောက်ကွယ်က သီအိုရီတွေကို သိထားသင့်တယ်တဲ့။ ဒါပေမဲ့ ကားမောင်းဖို့အတွက် ကားအင်ဂျင်ထဲမှာ ဘယ်လိုလုပ်တယ်ဆိုတာကို လေ့လာနေသလိုပဲ။ တော်ရုံနဲ့ ကားမောင်းနိုင်မှာ မဟုတ်ဘူး။ ပြီးတော့ အဲ့ဒီအင်ဂျင်ကို သိတဲ့အချိန်မှာ အာကီတက်ချာ မတူတဲ့ အင်ဂျင်တွေ ထွက်နေလောက်ပြီ။

Encapsulation ကို ကောင်းကောင်းနားလည်ရင် ဒီလိုအလုပ်တွေလုပ်မှာ မဟုတ်ပါဘူး။


What is Java I/O?


Java IO ဆိုတာဟာ Java Program ထဲကနေ Inputs Outputs တွေကို လုပ်နိုင်အောင် ကြိုရေးပေးထားတဲ့ API ပဲ ဖြစ်တယ်။ ဒါဆိုရင် IO ကို သိအောင် ဘာတွေလေ့လာထားဖို့လိုမှာလဲ။ File System ကိုနာလည်ထာဖို့တော့ လိုပါလိမ့်မယ်။ ပြီးမှ API ကို သုံးပြီး Input Output ကို ဘယ်လိုလုပ်မယ်ဆိုတာရယ် ဘယ်လို အရာမျိုးတွေကို Input လုပ်လို့ရမယ်ဆိုတာရယ်၊ အသုံးပြုနိုင်တဲ့ Interface Object တွေကို သိရှိထားရပါမယ်။

Java SE ရဲ့ java.io package ရဲ့ အောက်မှာ IO အတွက် API Class တွေ Interfaces တွေကို စုစည်းထားပါတယ်။ ကျွန်တော်တို့ Java IO အခန်းနဲ့ အောက်ပါ အကြောင်းအရာများကို လေ့လာသွားပါမယ်။


File Object


File System ထဲမှာ ရှိတဲ့ File တွေ Directory တွေရဲ့ Path Name တွေကို ကိုယ်စားပြုရန်အတွက် java.io.File Class ကို ပြင်ဆင်ထားပါတယ်။ File Object ကနေ File Directory တို့ရဲ့ Properties တွေကို သိရှိနိုင်သလို၊ File Directory တွေကို တည်ဆောက်နိုင်ပါတယ်။ တဖန် Directory ထဲမှာရှိတဲ့ File တွေကို ရှာဖွေတာတွေ၊ File တွေကို နာမည်ပြောင်းတာတွေ၊ တနေရာက တနေရာကို ပြောင်ရွှေ့တာတွေ၊ ပြီးတော့ ဖျက်ပစ်တာတွေ လုပ်နိုင်ပါတယ်။


I/O Streams


File ထဲမှာရှိတဲ့ Data တွေကို Read / Write လုပ်ဖို့အတွက်ပြင်ဆင်ထားတဲ့ Object တွေဖြစ်ပါတယ်။ Read / Write လုပ်မည့် Data Type အလိုက် အသုံးပြုရမည့် I/O Stream အမျိုးအစားတွေဟာ မတူညီပါဘူး။ ဘယ်လို Data အမျိုးအစားဆိုရင် ဘယ် Stream ကို သုံးမလဲ ဆိုတာတွေကို အသေအချာ ခွဲခြားသိနေဖို့လိုအပ်ပါတယ်။ နမူနာတွေနဲ့ I/O Stream တွေကို သဘောပေါက်အောင် လေ့လာသွားကြပါမယ်။


Serialization & Deserialization


JVM ရဲ့ Memory ပေါ်မှာရှိတဲ့ Object တွေကို တခြားတနေရာရာမှာ သွားပြီး သိမ်းတာကို Serialize လုပ်တယ်လို့ခေါ်ပါတယ်။ Object တွေကို File မှာ သွားသိမ်းမယ်။ ဒါမှမဟုတ် Internet ကနေ တစ်ခြားတစ်နေရာရာကို သွားပို့ပြီး သိမ်းထားမယ်။ ဒါမှမဟုတ် Session ပေါ်ကိုဖြတ်ပြီး မတူညီတဲ့ နေရာတွေမှာ Share လုပ်ပြီးသုံးမယ်။ ဒီလိုအခါမျိုးတွေမှာ Object တွေကို Serialize လုပ်ဖို့လိုအပ်ပါမယ်။ ဒီအခန်းမှာတော့ Object တွေကို Serialize လုပ်တယ်ဆိုတာဘယ်လိုဟာမျိုးလဲ။ ပြီးတော့ Serialzie လုပ်ဖို့ဘာလိုအပ်မလဲ။ ဘယ်လိုမျိုး Serialize လုပ်မလဲဆိုတာတွေကို လေ့လာပါမယ်။

တဖန် Serialized လုပ်ထားတဲ့ Object တွေကို JVM ရဲ့ Memory ပေါ်ကို ပြန်ပြီး ခေါ်ယူ အသုံးပြုတာကို Deserialize လုပ်တယ်လို့ခေါ်ပြီး Deserialize လုပ်တာကို ဘယ်လို လုပ်တာလဲ။ ပြီးတော့ သတိထားစရာ ဘာတွေရှိလဲဆိုတာကို လေ့လာသွားပါမယ်။

နောက်အခန်းတွေဖြင့် အထက်ပါ အကြောင်းအရာများကို ဆက်လက် ရေးသားသွားပါမယ်။

ဆက်ပါဦးမယ်
မင်းလွင်