본문 바로가기

Java-Study

Java Study : 11주차 - 자바 입출력

자바 입출력과 스트림

스트림

  • 자바의 모든 입출력은 스트림을 통해서 이루어 지는데 자바는 입출력 장치와 무관하고 일관성 있게 프로그램을
    구현할 수 있도록 일종의 가상 통로인 스트림을 제공한다.

 

입력 스트림과 출력 스트림

  • 입력 스트림
    • 어떤 대상으로부터 자료를 읽어 들일 때 사용하는 스트림
    • Input이나 Reader로 끝나는 이름의 클래스는 입력 스트림이다.
  • 출력 스트림
    • OutputStream이나 Writer로 끝나는 이름의 클래스는 출력 스트림이다.

 

바이트 단위 스트림과 문자 단위 스트림

  • 바이트 단위 스트림
    • 자바의 스트림은 원래 바이트 단위로 자료의 입출력이 이루어진다.
    • 스트림 클래스의 이름이 Stream으로 끝나는 경우는 바이트 단위를 처리하는 스트림이다.
  • 문자 단위 스트림
    • 자바에서는 입출력 중 가장 많이 사용하는 자료인 문자를 위해 문자 스트림을 별도로 제공한다.
    • Reader나 Writer로 끝나는 이름은 문자를 위한 스트림이다.

 

기반 스트림과 보조 스트림

  • 기반 스트림
    • 읽어 들일 곳이나 써야 할 곳에서 직접 읽고 쓸 수 있으며 입출력 대상에 직접 연결되어 생성되는 스트림이다.
    • FileInputStream, FileOutputStream, FileReader, FileWriter 등
  •  보조 스트림
    • 직접 읽고 쓰는 기능은 없기 때문에 항상 다른 스트림을 포함하여 생성된다.
    • InputStreamReader, OutputStreamReader, BufferedInputStream, BufferedOutputStream 등

 

 

표준 입출력

  • 자바는 화면에 출력하고 입력받는 표준 입출력 클래스를 미리 정의해 두었다.
  • 표준 입출력 클래스는 따로 만들 필요가 없다.

System.in으로 화면에서 문자 입력받기

문자 하나를 입력받기

package stream.inputstream;

import java.io.IOException;

public class SystemInTest1 {

    public static void main(String[] args) {
        System.out.println("알파벳 하나를 쓰고 [Enter]를 누르세요");

        int i;
        try {
            i = System.in.read();   //read() 메서드로 한 바이트 읽음
            System.out.println(i);
            System.out.println((char)i);    //문자로 변환하여 출력
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

문자 여러 개를 입력받기

package stream.inputstream;

import java.io.IOException;

public class SystemInTest2 {

    public static void main(String[] args) {
        System.out.println("알파벳 여러 개를 쓰고 [Enter]를 누르세요");

        int i;
        try {
            while( (i = System.in.read()) != '\n' ) {   //while문에서 read() 메서드로 한 바이틀르 반복해 읽음
                System.out.print((char)i);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

그 외 입력 클래스

Scanner

  • Scanner 클래스는 문자뿐 아니라 정수, 실수 등 다른 자료형도 읽을 수 있다.
  • Scanner 클래스에서 제공하는 메서드 
    • boolean nextBoolean() - boolean 자료를 읽는다.
    • byte nextByte() - 한 바이트 자료를 읽는다.
    • short nextShort() - short 자료형을 읽는다.
    • int nextInt() - int 자료형을 읽는다.
    • long nextLong() - long 자료형을 읽는다.
    • float nextFloat) - float 자료형을 읽는다.
    • double nextDouble - double 자료형을 읽는다.
    • String nextLine() - 문자열 String을 읽는다.
package stream.others;

import java.util.Scanner;

public class ScannerTest {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        System.out.println("이름:");
        String name = scanner.nextLine();   //문자열을 읽는 nextLine() 메서드로 이름과 직업을 입력받음
        System.out.println("직업:");
        String job = scanner.nextLine();
        System.out.println("사번:");
        int num = scanner.nextInt();    //int형을 읽는 nextInt() 메서드로 사번을 입력받음

        System.out.println(name);
        System.out.println(job);
        System.out.println(num);
    }
}

 

Console

  • Console 클래스는 System.in을 사용하지 않고 간단히 콘솔 내용을 읽을 수 있는 클래스이다.
  • 사용하는 메서드
    • String readLine() - 문자열을 읽는다.
    • char[] readPassword() - 사용자에게 문자열을 보여 주지 않고 읽는다.
    • Reader reader() - Reader 클래스를 반환한다.
    • PrintWriter writer() - PrintWriter 클래스를 반환한다.
package stream.others;

import java.io.Console;

public class ConsoleTest {

    public static void main(String[] args) {

        Console console = System.console(); //콘솔 클래스 반환

        System.out.println("이름:");
        String name = console.readLine();
        System.out.println("직업:");
        String job = console.readLine();
        System.out.println("비밀번호:");
        char[] pass = console.readPassword();
        String strPass = new String(pass);

        System.out.println(name);
        System.out.println(job);
        System.out.println(strPass);
    }

 

바이트 단위 스트림

InputStream

  • 바이트 단위로 읽는 스트림 중 최상위 스트림
  • 주로 사용하는 하위 클래스
    • FileInputStream - 파일에서 바이트 단위로 자료를 읽는다.
    • ByteArrayInputStream - byte 배열 메모리에서 바이트 단위로 자료를 읽는다.
    • FilterInputStream - 기반 스트림에서 자료를 읽을 때 추가 기능을 제공하는 보조 스트림의 상위 클래스이다.
  • 제공하는 메서드
    • int read() - 입력 스트림으로부터 한 바이트의 자료를 읽고, 읽은 자료의 바이트 수를 반환한다.
    • int read(byte[ ] b) - 입력 스트림으로부터 b[ ] 크기의 자료를 b[ ]에 읽고, 읽은 자료의 바이트 수를 반환한다.
    • int read(byet[ ] b, int off, int len) - 입력 스트림으로부터 b[ ] 크기의 자료를 b[ ]의 off 변수 위치부터 저장하며                                                               len 만큼 읽고, 읽은 자료의 바이트 수를 반환한다.
    • void close() - 입력 스트림과 연결된 대상 리소를 닫는다.

 

FileInputStream

  • 파일에서 바이트 단위로 자료를 읽어 들일 때 사용하는 스트림 클래스이다.
  • 스트림을 사용하기 위해서는 먼저 스트림 클래스를 생성해야 한다.
  • 생성자
    • FileInputStream(String name) - 파일 이름 name(경로 포함)을 매개변수로 입력 받아 입력 스트림을 생성한다.
    • FileInputStream(File f) - File 클래스 정보를 매개변수로 입력 받아 입력 스트림을 생성한다.
package stream.inputstream;
import java.io.FileInputStream;
import java.io.IOException;

public class FileInputStreamTest1 {

    public static void main(String[] args) {
        FileInputStream fis = null;

        try {
            fis = new FileInputStream("input.txt"); //input.txt 파일 입력 스트림 생성

            System.out.println((char)fis.read());
            System.out.println((char)fis.read());
            System.out.println((char)fis.read());

        } catch (IOException e) {
            System.out.println(e);
        } finally{
            try {
                fis.close();    //열린 스트림은 finally 블록에서 닫음
            } catch (IOException e) {
                System.out.println(e);
            } catch (NullPointerException e){   //스트림이 null인 경우
                System.out.println(e);
            }
        }
        System.out.println("end");
    }
}

 

input.txt 파일 생성후  끝까지 읽기

package stream.inputstream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest2 {

    public static void main(String[] args) {

        try(FileInputStream fis = new FileInputStream("input.txt")){
            int i;
            //i 값이 -1이 아닌 동안 read() 메서드로 한 바이트를 반복해 읽음
            while ( (i = fis.read()) != -1){
                System.out.println((char)i);
            }
            System.out.println("end");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

int read(byte[ ] b) 메서드로 읽기

package stream.inputstream;
import java.io.FileInputStream;
import java.io.IOException;

public class FileInputStreamTest3 {

    public static void main(String[] args) {

        try (FileInputStream fis = new FileInputStream("input.txt")){

            byte[] bs = new byte[10];
            int i;
            while ( (i = fis.read(bs)) != -1){
                for(int k= 0; k<i; k++){
                    System.out.print((char)bs[k]);
                }
                System.out.println(": " +i + "바이트 읽음" );
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("end");
    }
}

OutputStream

  • 바이트 단위로 쓰는 스트림 중 최상위 스트림
  • 자료의 출력 대상에 따라 다른 스트림을 제공한다.
    • FileOutputStream - 바이트 단위로 파일에 자료를 쓴다.
    • ByteArrayOutputStream - Byte 배열에 바이트 단위로 자료를 쓴다.
    • FilterOutputStream - 기반 스트림에서 자료를 쓸 때 추가 기능을 제공하는 보조 스트림의 상위 클래스이다.
  • 제공하는 메서드
    • void write() - 한 바이트를 출력한다.
    • void write(byte[ ] b) - b[ ] 배열에 있는 자료를 출력한다.
    • void write(byet[ ] b, int off, int len) - b[ ] 배열에 있는 자료의 off 변수 위치부터 len 개수 만큼 자료를 출력한다.
    • void flush() - 출력을 위해 잠시 자료가 머무르는 출력 버퍼를 강제로 비워 자료를 출력한다
    • void close() - 출력 스트림과 연결된 대상 리소를 닫는다. 출력 버퍼가 비워진다.

 

FileOutputStream

  • 파일에 바이트 단위 자료를 출력하기 위해 사용하는 스트림이다.
  • 생성자
    • FileOutputStream(String name) - 파일 이름 name(경로 포함)을 매개변수로 받아 출력 스트림을 생성한다.
    • FileOutputStream(String name, boolean append) 
      • 파일 이름 name(경로 포함)을 매개변수로 받아 입력 스트림을 생성한다.
        append 값이 true 이면 파일 스트림을 닫고 다시 생성할 때 파일의 끝에 이어서 쓴다. 
      • 디폴트 값은 false이다.
    • FileOutputStream(File f, ) - File 클래스 정보를 매개변수로 받아 출력 스트림을 생성한다.
    • FileOutputStream(Filen f, boolean append)
      • File 클래스 정보를 매개변수로 받아 출력 스트림을 생성한다.
        append 값이 true이면 파일 스트림을 닫고 다시 생성할 때 파일의 끝에 이어서 쓴다.
      • 디폴트 값은 false이다.

 

write() 메서드 사용하기

package stream.outputstream;

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

public class FileOutputStreamTest1 {

    public static void main(String[] args) {

        try(FileOutputStream fos = new FileOutputStream("output.txt")){
            fos.write(65);  //A, FileOutputStream은 파일에 숫자를 쓰면 해당하는 아스키 코드 값으로 변환됨
            fos.write(66);  //B
            fos.write(67);  //C
        }catch(IOException e) {
            e.printStackTrace();
        }
        System.out.println("출력이 완료되었습니다.");
    }
}

코드를 실행하면 output.txt 파일이 생성되고 입력한 값이 쓰여져 있다.

 

write(byte[ ] b) 메서드 사용하기

package stream.outputstream;

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

public class FileOutputStreamTest2 {

    public static void main(String[] args) throws IOException {

        FileOutputStream fos = new FileOutputStream("output2.txt",true);
        try(fos){ //java 9 부터 제공되는 기능

            byte[] bs = new byte[26];
            byte data = 65;        //'A' 의 아스키 값
            for(int i = 0; i < bs.length; i++){  // A-Z 까지 배열에 넣기
                bs[i] = data;
                data++;
            }

            fos.write(bs);  //배열 한꺼번에 출력하기
        }catch(IOException e) {
            e.printStackTrace();
        }
        System.out.println("출력이 완료되었습니다.");
    }
}

 

write(byte[ ] b, int off, int len) 메서드 사용하기

package stream.outputstream;

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

public class FileOutputStreamTest3 {

    public static void main(String[] args) {

        try(FileOutputStream fos = new FileOutputStream("output3.txt"))
        {

            byte[] bs = new byte[26];
            byte data = 65;     //'A' 의 아스키 값
            for(int i = 0; i < bs.length; i++){  // A-Z 까지 배열에 넣기
                bs[i] = data;
                data++;
            }
            fos.write(bs, 2, 10);   // 배열의 2 번째 위치부터 10 개 바이트 출력하기
        }catch(IOException e) {
            e.printStackTrace();
        }
        System.out.println("출력이 완료되었습니다.");
    }
}

 

문자 단위 스트림

Reader

  • 문자 단위로 읽는 스트림 중 최상위 스트림으로 다음 하위 클래스를 주로 사용한다.
    • FileReader - 파일에서 문자 단위로 읽는 스트림 클래스이다.
    • InputStreamReader - 바이트 단위로 읽은 자료를 문자로 변환해 주는 보조 스트림 클래스이다.
    • BufferedReader - 문자로 읽을 때 배열을 제공하여 한꺼번에 읽을 수 있는 기능을 제공해 주는 보조 스트림이다.
  • 제공하는 메서드
    • int read() - 파일로부터 한 문자를 읽고, 값을 반환한다.
    • int read(char[ ] buf) - 파일로부터 buf 배열에 문자를 읽는다.
    • int read(char[ ] buf, int off, int len) - 파일로부터 buf 배열의 off 위치에서부터 len 개수만큼 문자를 읽는다.
    • void close() - 스트림과 연결된 파일 리소스를 닫는다.

 

FileReader

  • 생성자
    • FileReader(String name) - 파일 이름 name(경로 포함)을 매개변수로 받아 입력 스트림을 생성한다.
    • FileReader(File f) - File 클래스 정보를 매개변수로 받아 입력 스트림을 생성한다.
package stream.reader;

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

public class FileReaderTest {

    public static void main(String[] args) {

        try(FileReader fr = new FileReader("reader.txt")){
            int i;
            while( (i = fr.read()) != -1){
                System.out.print((char)i);
            }
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

Writer

  • 문자 단위로 풀력하는 스트림 중 최상위 스트림으로 다음 하위 클래스를 주로 사용한다.
    • FileWriter - 파일에 문자 단위로 출력하는 스트림 클래스이다.
    • OutputStreamWriter - 파일에 바이트 단위로 출력한 자료를 문자로 변환해 주는 보조 스트림이다.
    • BufferedWriter - 문자로 쓸 때 배열을 제공하여 한꺼번에 쓸 수 있는 기능을 제공해 주는 보조 스트림이다.
  • 제공하는 메서드
    • void write(int c) - 한 문자를 파일에 출력한다.
    • void write(char[ ] buf) - 문자 배열 buf의 내용을 파일에 출력한다.
    • void write(char[ ] buf, int off, int len) - 문자 배열 buf의 off 위치에서부터 len 개수의 문자를 파일에 출력한다.
    • void write(String str) - 문자열 str을 파일에 출력한다.
    • void write(String str, int off, int len) - 문자열 str의 off번째 문자부터 len 개수만큼 파일에 출력한다.
    • void flush() - 파일에 출력하기 전에 자료가 있는 공간을 비워 출력한다.
    • void close() - 파일과 연결된 스트림을 닫는다. 이 때 출력 버퍼도 지워진다.

 

FileWriter

  • 생성자
    • FilerWriter(String name) - 파일 이름 name(경로 포함)을 매개변수로 받아 출력 스트림을 생성한다.
    • FileWriter(String name, boolean append)
      • 파일 이름 name(경로 포함)을 매개변수로 받아 출력 스트림을 생성한다.
      • append 값이 true이면 파일 스트림을 닫고 다시 생성할 때 파일 끝에 이어서 쓴다.
      • 기본 값은 false이다.
    • FileWriter(File f, ) - File 클래스 정보를 매개변수로 받아 출력 스트림을 생성한다.
    • FileWriter(File f, boolean append)
      • File 클래스 정보를 매개변수로 받아 출력 스트림을 생성한다.
      • append 값이 true이면 파일 스트림을 닫고 다시 생성할 때 파일 끝에 이어서 쓴다.
      • 기본 값은 false 이다.
package stream.writer;

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

public class FileWriterTest {

    public static void main(String[] args) {

        try(FileWriter fw = new FileWriter("writer.txt")){
            fw.write('A');    // 문자 하나 출력
            char buf[] = {'B','C','D','E','F','G'};

            fw.write(buf); //문자 배열 출력
            fw.write("안녕하세요. 잘 써지네요"); //String 출력
            fw.write(buf, 1, 2); //문자 배열의 일부 출력
            fw.write("65");  //숫자를 그대로 출력
        }catch(IOException e) {
            e.printStackTrace();
        }

        System.out.println("출력이 완료되었습니다.");
    }
}

 

보조 스트림

  • 보조 스트림은 보조 기능을 추가하는 스트림이다.
  • 다른 말로 Wrapper 스트림이라고도 하며, 스스로는 입출력 기능이 없기 때문에 보조 기능을 추가한다.

FilterInputStream과 FilterOutputStream

  • 보조 스트림의 상위 클래스로 모든 보조 스트림은 둘 중 하나를 상소받는다.
  • 생성자
    • protected FilterInputStream(InputStream in) - 생성자의 매개변수로 InputStream을 받는다.
    • public FilterOutputStream(OutputStream out) - 생성자의 매개변수로 OutputStream을 받는다.

 

InputStreamReader와 OutputStreamReader

  • 생성된 바이트 스트림을 문자로 변환해 주는 보조 스트림
  • 생성자
    • InputStreamReader(InputStream in) - InputStream 클래스를 생성자의 매개변수로 받아 Reader를 생성한다.
    • InputStreamReader(InputStream in, Charset cs) 
      • InputStream과 Charset 클래스를 매개변수로 받아 Reader를 생성한다.
    • InputStreamReader(InputStream in, CharsetDecoder dec)
      • InputStream과 CharsetDecoder를 매개변수로 받아 Reader를 생성한다.
    • InputStreamReader(InputStream in, String charsetName)
      • InputStream과 String으로 문자 세트 이름을 받아 Reader를 생성한다.
package stream.decorator;

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

public class InputStreamReaderTest {

    public static void main(String[] args) {
        
        //보조 스트림인 InputStreamReader의 매개변수로 기반 스트림인 FileInputStream을 받아 생성함
        try(InputStreamReader isr = new InputStreamReader(new FileInputStream("reader.txt"))){
            int i;
            while( (i = isr.read()) != -1){  //파일의 끝인 -1이 반환될 때까지 보조 스트림으로 읽습니다.
                System.out.print((char)i);
            }
        }catch(IOException e) {
            e.printStackTrace();
        }
    }
}

 

Buffered 스트림

  • 이미 생성된 스트림에 배열 기능을 추가해 더 빠르게 입출력을 실행할 수 있는 버퍼링 기능을 제공한다.
  • 제공하는 스트림 클래스
    • BufferedInputStream - 바이트 단위로 읽는 스트림에 버퍼링 기능을 제공한다.
    • BufferedOutputStream - 바이트 단위로 출력하는 스트림에 버퍼링 기능을 제공한다.
    • BufferedReader - 문자 단위로 읽는 스트림에 버퍼링 기능을 제공한다.
    • BufferedWriter - 문자 단위로 출력하는 스트림에 버퍼링 기능을 제공한다.
  • BufferedInputStream의 생성사
    • BufferedInputStream(InputStream in)
      • InputStream 클래스를 생성자의 매개변수로 받아 BufferedInputStream을 생성한다.
    • BufferedInputStream(InputStream in, int size)
      • InputStream 클래스와 버퍼 크기를 생성자의 매개변수로 받아 BufferedInputStream을 생성한다.

버퍼링 기능으로 파일 복사하기 -> 버퍼링 기능을 사용하지 않았을 때 보다 시간이 적게 걸린다.

package stream.decorator;

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

public class BufferedStreamTest {

    public static void main(String[] args) {

        long millisecond = 0;
        try(FileInputStream fis = new FileInputStream("a.zip");
            FileOutputStream fos = new FileOutputStream("copy.zip");
            BufferedInputStream bis = new BufferedInputStream(fis);
            BufferedOutputStream bos = new BufferedOutputStream(fos)){

            millisecond = System.currentTimeMillis();

            int i;
            while( ( i = bis.read()) != -1){
                bos.write(i);
            }

            millisecond = System.currentTimeMillis() - millisecond;
        }catch(IOException e) {
            e.printStackTrace();
        }

        System.out.println("파일 복사 하는 데 " + millisecond + " milliseconds 소요되었습니다.");
    }
}

 

DataInputStream과 DataOutputStream

  • 메모리에 저장된 0, 1 상태를 그대로 읽거나 쓰기 때문에 자료형의 크기가 그대로 보존된다.
  • 생성자
    • DataIntputStream(InputStream in) - InputStream을 생성자의 매개변수로 받아 DataInputStream을 생성한다.
    • DataOutputStream(OutputStream out) - OutputStream을 생성자의 매개변수로 받아 DataOutputStream을 생성
  •  DataInputStream에서 제공하는 메서드
    • byte readByte() - 1바이트를 읽어 반환한다.
    • boolean readBoolean() - 읽은 자료가 0이 아니면 true를, 0이면 false를 반환한다.
    • char readChar() - 한 문자를 읽어 반환한다.
    • short readShort() - 2바이트를 읽어 정수 값을 반환한다.
    • int readInt() - 4바이트를 읽어 정수 값을 반환한다.
    • long readLong() - 8바이트를 읽어 정수 값을 반환한다.
    • float readFloat() - 4바이트를 읽어 실수 값을 반환한다.
    • double readDouble() - 8바이트를 읽어 실수 값을 반환한다.
    • String readUTF() - 수정된 UTF-8 인코딩 기반으로 문자열을 읽어 반환한다.
  • DataOutputStream에서 제공하는 메서드
    • void writeByte(int v) - 1바이트의 자료를 출력한다.
    • void writeBoolean(boolean v) - 1바이트 값을 출력한다.
    • void writeChar(int v) - 2바이트를 출력한다.
    • void writeShort(int v) - 2바이트를 출력한다.
    • void writeInt(int v) - 4바이트를 출력한다.
    • void writeLong(ling v) - 8바이트를 출력한다. 
    • void writeFloat(float v) - 4바이트를 출력한다.
    • void writeDouble(double v) - 8바이트를 출력한다.
    • void writeUTF(String str) - 수정된 UTF-8 인코딩 기반으로 문자열을 출력한다.
package stream.decorator;

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

public class DataStreamTest {

    public static void main(String[] args) {


        try(FileOutputStream fos = new FileOutputStream("data.txt");
            DataOutputStream dos = new DataOutputStream(fos))
        {

            dos.writeByte(100);     //각 자료형에 맞게 자료를 씀
            dos.writeChar('A');
            dos.writeInt(10);
            dos.writeFloat(3.14f);
            dos.writeUTF("Test");
        }catch(IOException e) {
            e.printStackTrace();
        }

        try(FileInputStream fis = new FileInputStream("data.txt");
            DataInputStream dis = new DataInputStream(fis))
        {

            System.out.println(dis.readByte());     //자료형에 맞게 자료를 읽어 출력함
            System.out.println(dis.readChar());     //파일에 쓴 순서와 같은 순서, 같은 메서드로 읽어야 함
            System.out.println(dis.readInt());
            System.out.println(dis.readFloat());
            System.out.println(dis.readUTF());
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

직렬화

직렬화와 역직렬화

  • 인스턴스의 순간 상태를 그대로 저장하거나 네트워크를 통해 전송하는것을 직렬화라고 한다.
  • 저장된 내용이나 전송받은 내용을 다시 복원하는 것을 역직렬화라고 한다.
  • 생성자
    • ObjectInputStream(InputStream in)
      • InputStream을 생성자의 매개변수로 받아 ObjectInputStream을 생성한다.
    • ObjectOutputStream(OutputStream out)
      • OutputStream을 생성자의 매개변수로 받아 ObjectOutputStrean을 생성한다.

직렬화 테스트하기

package stream.serialization;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;


class Person implements Serializable{   //직렬화를 하겠다는 의도를 표시

    private static final long serialVersionUID = -1503252402544036183L;     //버전 관리를 위한 정보

    String name;
    transient String job;   //transient 예약어를 사용하면 직렬화되고 복원되는 과정에서 제외된다.


    public Person() {}

    public Person(String name, String job) {
        this.name = name;
        this.job = job;
    }

    public String toString()
    {
        return name + "," + job;
    }
}

public class SerializationTest {

    public static void main(String[] args) throws ClassNotFoundException {

        Person personAhn = new Person("안재용", "대표이사");
        Person personKim = new Person("김철수", "상무이사");

        try(FileOutputStream fos = new FileOutputStream("serial.out");
            ObjectOutputStream oos = new ObjectOutputStream(fos)){

            oos.writeObject(personAhn);     //personAhn과 personKim의 값을 파일에 씀(직렬화)
            oos.writeObject(personKim);

        }catch(IOException e) {
            e.printStackTrace();
        }

        try(FileInputStream fis = new FileInputStream("serial.out");
            ObjectInputStream ois = new ObjectInputStream(fis)){

            Person p1 = (Person)ois.readObject();   //personAhn과 personKim의 값을 파일에서 읽어들임(역직렬화)
            Person p2 = (Person)ois.readObject();

            System.out.println(p1);
            System.out.println(p2);
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

Externalizable 인터페이스

  • 직렬화하는 데 사용하는 또 다른 인터페이스오 Serializable 인터페이스와 달리 구현해야 할 메서드가 있다.
  • 객체의 직렬화와 역직렬화를 프로그래머가 직접 세밀하게 제어하고자 할 때 사용하며, 그 메서드에 내용을 구현한다.
package stream.serialization;

import java.io.Externalizable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

class Dog implements Externalizable{

    String name;

    public Dog() {}

    //Externalizable 인터페이스의 메서드 구현
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeUTF(name);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        name =in.readUTF();
    }

    public String toString() {
        return name;
    }
}

public class ExternalizableTest {

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        Dog myDog = new Dog();
        myDog.name = "멍멍이";


        FileOutputStream fos = new FileOutputStream("external.out");
        ObjectOutputStream oos = new ObjectOutputStream(fos);

        try(fos; oos){
            oos.writeObject(myDog);
        }catch(IOException e) {
            e.printStackTrace();
        }


        FileInputStream fis = new FileInputStream("external.out");
        ObjectInputStream ois = new ObjectInputStream(fis);

        Dog dog = (Dog)ois.readObject();

        System.out.println(dog);
    }
}

 

그 외 입출력 클래스

File 클래스

  • 파일이라는 개념을 추상화한 클래스
  • 입출력 기능은 없지만 파일 자체의 경로나 정보를 알 수 있고, 생성도 가능하다.
  • 생성자
    • File(String pathname) - pathname을 매개변수로 받아 파일을 생성한다.
package stream.others;

import java.io.File;
import java.io.IOException;

public class FileTest {

    public static void main(String[] args) throws IOException {

        File file = new File("D:\\easyspub\\JAVA_LAB\\Chapter15\\newFile.txt");
        file.createNewFile();

        System.out.println(file.isFile());
        System.out.println(file.isDirectory());
        System.out.println(file.getName());
        System.out.println(file.getAbsolutePath());
        System.out.println(file.getPath());
        System.out.println(file.canRead());
        System.out.println(file.canWrite());

        file.delete();
    }
}

 

RandomAccessFile 클래스

  • 입출력 클래스 중 유일하게 파일 입출력을 동시에 할 수 있는 클래스
  • 생성자
    • RandomAccessFile(File file, String mode)
      • 입출력을 할 File과 입출력 mode를 매개변수로 받는다.
      • mode에는 읽기 전용 "r"과 쓰기 기능인 "rw"를 사용할 수 있다.
    • RandomAccessFile(String file, String mode)
      • 입출력을 할 파일 이름을 문자열로 받고 입출력 mode를 매개변수로 받는다.
      • mode에는 읽기 전용 "r"과 쓰기 기능인 "rw"를 사용할 수 있다.
package stream.others;

import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomAccessFileTest {

    public static void main(String[] args) throws IOException {
        RandomAccessFile rf = new RandomAccessFile("random.txt", "rw");
        rf.writeInt(100);
        System.out.println("파일 포인터 위치:" + rf.getFilePointer());     //getFilePointer() = 파일 포인터 위치를 반환하는 메서드
        rf.writeDouble(3.14);
        System.out.println("파일 포인터 위치:" + rf.getFilePointer());
        rf.writeUTF("안녕하세요");
        System.out.println("파일 포인터 위치:" + rf.getFilePointer());

        rf.seek(0);     //파일 포인터 위치를 맨 처음으로 옮기고 위치를 출력함
        System.out.println("파일 포인터 위치:" + rf.getFilePointer());

        int i = rf.readInt();
        double d = rf.readDouble();
        String str = rf.readUTF();

        System.out.println("파일 포인터 위치:" + rf.getFilePointer());     //읽기가 끝난 후 파일 포인터 위치를 출력함
        System.out.println(i);
        System.out.println(d);
        System.out.println(str);
    }
}