songin.dev님의 블로그

[Do it! 자바 프로그래밍 입문] 15 자바 입출력 본문

Developer/Langauge

[Do it! 자바 프로그래밍 입문] 15 자바 입출력

songin.dev 2022. 6. 13. 18:02
728x90
자바 입출력

스트림이란?

네트워크에서 자료의 흐름이 물과 같다는 의미에서 유래

다양한 입출력 장치에 독립적으로 일관성 있는 입출력을 제공하는 방식

Do it 자바 프로그래밍 입문

입출력이 구현되는 곳 

파일 디스크, 키보드, 마우스, 메모리 네트워크 등

 

스트림의 구분

대상 기준

입력 스트림 / 출력 스트림

자료의 종류

바이트 스트림 / 문자 스트림

기능

기반 스트림 / 보조 스트림

 

입력 스트림과 출력 스트림

입력 스트림

대상으로부터 자료를 읽어 들이는 스트림

출력 스트림

대상으로 자료를 출력하는 스트림

Do it 자바  프로그래밍 입문

스트림의 종류

Do it 자바 프로그래밍 입문

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

바이트 단위 스트림

동영상, 음악 파일 등을 읽고 쓸 때 사용

문자 단위 스트림

바이트 단위로 자료를 처리하면 문자는 깨짐

2바이트 단위로 처리하도록 구현된 스트림

Do it 자바 프로그래밍 입문

스트림의 종류

Do it 자바 프로그래밍 입문

기본 스트림과 보조 스트림

기반 스트림

대상에 직접 자료를 읽고 쓰는 기능의 스트림

보조 스트림

직접 읽고 쓰는 기능은 없이 추가적인 기능을 더해주는 스트림

보조 스트림은 직접 읽고 쓰는 기능은 없으므로 항상 기반 스트림이나 또 다른 보조 스트림을 생성자 매개변수로 포함함

Do it 자바 프로그래밍 입문

스트림의 종류

Do it 자바 프로그래밍 입문

표준 입출력

// System 클래스의 표준 입출력 멤버

public class System{
    public static PrintStream out;
    public static InputStream in;
    public static PrintStream err;
}

System.out
    표준 출력(모니터)스트림
    System.out.println("에러메시지");
    
System.in
    표준 입력(키보드)스트림
    int d = System.in.read(); // 한 바이트 읽어내기
    
System.err
    표준 에러 출력(모니터)스트림
    System.err.println("데이터");

System.in 사용하기 예제

public class SystemInTest2 {
    public static void main(String[] args) {
        System.out.println("알파벳 여러 개를 쓰고 [Enter]를 누르세요");
    int i;
    try {
        while((i = System.in.read()) != -1) {
            System.out.println((char)i);
        }
        // while문에서 read() 메서드로 한 바이트를 반복해 읽음
    }catch (IOException e) {
        e.printStackTrace();
    }
    }
}

Scanner 클래스

java.util 패키지에 있는 입력 클래스

문자뿐 아니라 정수, 실수 등 다른 자료형도 읽을 수 있음

여러 대상에서 자료를 읽을 수 있음(콘솔, 파일 등)

 

생성자

생성자 설명
Scanner(File source) 파일을 매개변수로 받아 Scanner를 생성합니다.
Scanner(InputStream source) 바이트 스트림을 매개변수로 받아 Scanner를 생성합니다.
Scanner(String source) String을 매개변수로 받아 Scanner를 생성합니다.

메서드

메서드 설명
boolean nextBoolean() boolean 자료를 읽습니다.
byte nextByte() 한 바이트 자료를 읽습니다.
short nextShort() short 자료형을 읽습니다.
int nextInt() int 자료형을 읽습니다.
long nextLong() long 자료형을 읽습니다.
float nextFloat() float 자료형을 읽습니다.
double nextDouble() double 자료형을 읽습니다.
String nextLine() 문자열 String을 읽습니다.

Console 클래스

System.in을 사용하지 않고 콘솔에서 표준 입력을 할 수 있음

이클립스와는 연동되지 않음

command창에서 입력함

 

메서드

메서드 설명
String readLine() 문자열을 읽습니다.
char[] readPassword() 사용자에게 문자열을 보여주지 않고 읽습니다.
Reader reader() Reader 클래스를 반환합니다.
PrintWriter writer() PrintWriter 클래스를 반환합니다.

Console 클래스 예제

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(byte b[], int off, int len) 입력 스트림으로부터 b[] 크기의 자료를 b[]의 off 변수 위치부터 저장하여 len만큼 읽습니다. 읽은 자료의 바이트 수를 반환합니다.
void close() 입력 스트림과 연결된 대상 리소스를 닫습니다. 
(예 : fileInputStream인 경우 파일 닫음)

FileInputStream 클래스

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

byte 배열로 읽기

A-Z까지의 알파벳을 10 크기의 배열로 읽을 땐 마지막에는 자료가 남게 된다.

Do it 자바 프로그래밍 입문

바이트 단위 스트림 - OutputStream

바이트 단위 출력용 최상위 스트림

추상 메서드를 포함한 추상 클래스로 하위 클래스가 구현하여 사용

 

주요 하위 클래스

스트림 클래스 설명
FileOutputStream 바이트 단위로 파일에 자료를 씁니다.
ByteArrayOutputStream Byte 배열에 바이트 단위로 자료를 씁니다.
FilterOutputStream 기반 스트림에서 자료를 쓸 때 추가 기능을 제공하는 보조 스트림의 상위 클래스입니다.

메서드

메서드 설명
void write(int b) 한 바이트를 출력합니다.
void write(byte[] b) b[] 배열에 있는 자료를 출력합니다.
void write(byte b[], int off, int len) b[] 배열에 있는 자료의 off 위치부터 len 개수만큼 자료를 출력합니다.
void flush() 출력을 위해 잠시 자료가 머무르는 출력 버퍼를 강제로 비워 자료를 출력합니다.
void close() 출력 스트림과 연결된 대상 리소스를 닫습니다. 출력 버퍼가 비워집니다.(예 : FileOutputStream인 경우 파일 닫음)

flush() 와 close() 메서드

출력 버퍼를 비울때 flush() 메서드를 사용

close() 메서드 내부에서 flush()가 호출되므로 close() 메서드가 호출되면 출력 버퍼가 비워짐

 

문자 단위 스트림 - Reader

문자 단위로 읽는 최상위 스트림

하위 클래스에서 상속 받아 구현함

스트림 클래스 설명
FileReader 파일에서 문자 단위로 읽는 스트림 클래스입니다.
InputStreamReader 바이트 단위로 읽은 자료를 문자로 변환해 주는 보조 스트림 클래스입니다.
BufferedReader 문자로 읽을 때 배열을 제공하여 한꺼번에 읽을 수 있는 기능을 제공해주는 보조 스트림입니다.

주요 메서드

메서드 설명
int read() 파일로부터 한 문자를 읽습니다. 읽은 값을 반환합니다.
int read(char[] buf) 파일로부터 buf 배열에 문자를 읽습니다.
int read(char[] buf, int off, int len) 파일로부터 buf 배열의 off 위치에서부터 len 개수만큼 문자를 읽습니다.
void close() 스트림과 연결된 파일 리소스를 닫습니다.

FileWriter 클래스

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("안녕하세요. 잘 써지네요"); // 문자열 출력
            fw.write(buf, 1, 2); // 문자 배열의 일부 출력
            fw.write("65"); // 숫자 그대로 출력
        } catch(IOException e) {
            e.printStackTrace();
        }
        System.out.println("출력이 완료되었습니다.");
    }

보조 스트림

실제 읽고 쓰는 스트림이 아닌 보조적인 기능을 추가하는 스트림

데코레이션 패턴

FileterInputStream과 FileterOutputStream이 보조 스트림의 상위 클래스

생성자의 매개 변수로 다른 스트림을 가짐

생성자 설명
protected FilterInputStream(InputStream in) 생성자의 매개변수로 InputStream을 받습니다.
public FilterOutputStream(OutputStream out) 생성자의 매개변수로 OutputStream을 받습니다.

Do it 자바 프로그래밍 입문

InputStreamReader와 OutputStreamWriter

바이트 단위로 읽거나 쓰는 자료를 문자로 변환해주는 보조 스트림

FileInputStream(바이트 스트림)으로 읽은 자료를 문자와 변환하는 예

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

Buffered 스트림

내부적으로 8192 바이트 배열을 가지고 읽거나 쓰기 기능을 제공하여 속도가 빨라짐

스트림 클래스 설명
BufferedInputStream 바이트 단위로 읽는 스트림에 버퍼링 기능을 제공합니다.
BufferedOutputStream 바이트 단위로 출력하는 스트림에 버퍼링 기능을 제공합니다.
BufferedReader 문자 단위로 읽는 스트림에 버퍼링 기능을 제공합니다.
BufferedWriter 문자 단위로 출력하는 스트림에 버퍼링 기능을 제공합니다.

DataInputStream과 DataOutputStream

자료가 메모리에 저장된 0, 1 상태 그대로 읽거나 쓰는 스트림

 

읽는 메서드

메서드 설명
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 인코딩 기반으로 문자열을 읽어 반환합니다.

쓰는 메서드

메서드 설명
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(long v) 8바이트를 출력합니다.
void writeFloat(float v) 4바이트를 출력합니다.
void writeDouble(double v) 8바이트를 출력합니다.
void writeUTF(String str) 수정된 UTF-8 인코딩 기반으로 문자열을 출력합니다.

직렬화(serialization)

인스턴스의 상태를 그대로 저장하거나(serialization) 다시 복원하는(deserialization) 방식

파일에 쓰거나 네트워크로 전송

 

ObjectInputStream과 ObjectOutputStram 사용

생성자 설명
ObjectInputStream(InputStream in) InputStream을 생성자의 매개변수로 받아 ObjectInputStream을 생성합니다.
ObjectOutputStream(OutputStream out) OutputStram을 생성자의 매개변수로 받아 ObjectOutputStream을 생성합니다.

Serializable 인터페이스

직렬화는 인스턴스 내용이 외부로 유출되는 것이므로 프로그래머가 직렬화 의도를 표시해야 함

구현 코드가 없는 maker interface

class Person implements Serializable { // 직렬화하겠다는 의도를 표시
    ...
    String name;
    String job;
    ...
}

그 외 입출력 클래스 

File 클래스

파일 개념을 추상화한 클래스

입출력 기능은 없고 파일의 속성, 경로, 이름 등을 알 수 있음

RandomAccessFile 클래스

입출력 클래스 중 유일하게 파일 입출력을 동시에 할 수 있는 클래스

파일 포인터가 있어서 읽고 쓰는 위치의 이동이 가능함

다양한 자료형에 대한 메서드가 제공됨

 

RandomAccessFile 예제

public class RandomAccessFileTest {
    public static void main(String[] args) throws IOException {
        ...
        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);
    }
}

 

반응형
Comments