Post

자바 I/O Stream

1. Stream이란? 2. Stream 클래스 3. 보조 Stream 클래스 4. Stream 사용 예시 5. 정리

Stream이란?

Stream은 데이터가 흐르는 통로입니다.

‘데이터가’, ‘흐르는’, ‘통로’를 나눠서 살펴보겠습니다.

데이터가

컴퓨터는 이진수, 즉 0과 1로만 모든 데이터를 다룹니다.

숫자, 글자, 동영상, 파일, 모니터에 띄워지는 화면 등 모든 것은 결국 0과 1로 변환돼서 다뤄집니다.

숫자의 경우 1의 보수, 2의 보수 등의 기법이 활용되고, 그 외의 경우 특정 이진수마다 하나하나 사전처럼 대응시키는 식으로 처리합니다. 11101010 10110000 10000000 는 한글 문자 ‘가’라고 인식하자고 약속하는 식이죠. (UTF-8에서 실제로 이렇게 대응시킵니다.)

흐르는

그리고 그 데이터는 컴퓨터 안에서 계속 흘러다닙니다.

  • System.out.print("") 함수를 사용하면 “” 문자열이 출력 콘솔로 흘러갑니다.
  • 키보드 자판을 누르면 해당하는 글자가 여러 중간 지점을 거쳐 커서에 입력이 됩니다.
  • 주소창에 네이버를 입력하면 네이버 웹서버로 웹페이지 내용을 요청하는 데이터가 네이버 서버로 흘러갑니다.
  • 파일을 실행하면 그 파일의 내용이 RAM 메모리로 흘러가고, 실행할 바이트 코드가 하나씩 CPU로 흘러갑니다.

아마 여러 컴퓨터 부품에 서로 연결된 선을 따라서 계속 데이터가 흐르고 있겠죠?

통로

물리적으로 데이터가 흐르는 통로는 부품과 부품을 잇는 ‘선’일 것입니다.

논리적으로 데이터가 흐르는 통로가 바로 Stream입니다.

‘데이터가 흐르는 통로’라는 개념을 Stream이라는 클래스로 추상화한 것입니다.

Stream 클래스

(참고) 이 글에서는 입출력 Stream 클래스를 통틀어서 ‘Stream 클래스’라고 부르지만 상속관계 상 Reader, Writer는 InputStream, OutputStream에 속하지 않습니다.

이제 실제 Stream 자바 클래스에 대해서 알아보겠습니다.

InputStream, OutputStream

바이트 단위로 입력 또는 출력을 하는 클래스입니다. (컴퓨터에서 데이터는 기본적으로 바이트 단위로 흘러다닙니다.)

추상 클래스이기 때문에 이 클래스만 가지고는 아무것도 할 수 없습니다. 상속하여 구현체를 만들어야 합니다.

FileInputStream, FileOutputStream

InputStream, OutputStream의 대표적인 구현체입니다.

파일을 대상으로 입력 또는 출력을 하는 클래스입니다.

Reader, Writer

String 단위로 입력 또는 출력을 하는 클래스입니다.

하지만 위에서 말씀드렸다시피 컴퓨터에서 데이터는 기본적으로 바이트 단위로 흘러다닙니다.

그렇기 때문에 Reader, Writer 내부에서 결국 String을 바이트로 변환해 InputStream, OutputStream을 통해 입출력을 합니다.

추상 클래스이기 때문에 이 클래스만 가지고는 아무것도 할 수 없습니다. 상속하여 구현체를 만들어야 합니다.

FileReader, FileWriter

Reader, Writer의 대표적인 구현체입니다.

파일을 대상으로 String 단위로 입력 또는 출력을 하는 클래스입니다.

보조 Stream 클래스

(참고) FilterInputStream, FilterOutputStream이라는 보조 스트림들의 슈퍼 클래스이자 추상 클래스가 있습니다.

Reader, Writer는 상속 관계상 InputStream, OutputStream에 속하지 않기에 FilterInputStream, FilterOutputStream에도 속하지 않습니다.

위에서 설명한 Stream 클래스들을 ‘본 Stream’이라고 부르겠습니다.

보조 Stream 클래스는 본 Stream을 감싸서 추가 기능을 제공하는 클래스입니다. (데코레이터 패턴)

InputStreamReader, OutputStreamWriter

InputStream/OutputStream에 입출력 단위를 String도 지원하게 하는 추가 기능을 제공합니다.

DataInputStream, DataOutputStream

InputStream/OutputStream에 int, byte, boolean, short, char, long, double, String 등의 자바 데이터 타입을 지원하게 하는 추가 기능을 제공합니다.

BufferedInputStream, BufferedOutputStream

InputStream/OutputStream에 버퍼링 기능을 제공합니다.

버퍼링이란

아래와 같이 한 바이트씩 입력 또는 출력을 하지 않고

1
2
3
4
5
6
7
8
9
10
11
try (InputStream fis = new FileInputStream("input.txt");
     OutputStream fos = new FileOutputStream("output.txt")
) {
        int byteData;
        while ((byteData = fis.read()) != -1) {
            fos.write(byteData);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

아래와 같이 일정 바이트씩 모아서 한번에 입력 또는 출력을 하는 최적화 기법을 말합니다.

1
2
3
4
5
6
7
8
9
10
11
try (InputStream fis = new FileInputStream(inputFile);
     OutputStream fos = new FileOutputStream(outputFile)
) {
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = fis.read(buffer)) != -1) {
        fos.write(buffer, 0, bytesRead);
    }
} catch (IOException e) {
    e.printStackTrace();
}

BufferedReader, BufferedWriter

Reader와 Writer에 버퍼링 기능을 제공합니다.

PrintStream

OutputStream에 아래와 같이 다양한 형식으로 출력하는 기능을 제공합니다.

1
2
3
4
5
6
7
8
9
10
PrintStream ps = System.out;
ps.print("This is printed without a newline.");
ps.println("Hello, World!");
ps.printf("Formatting numbers: %d and %.2f%n", 123, 45.678);

// 콘솔이 아닌 다른 OutputStream에도 사용할 수 있습니다.
PrintStream ps = new PrintStream(new FileOutputStream("output.txt"));
ps.print("This is printed without a newline.");
ps.println("Hello, World!");
ps.printf("Formatting numbers: %d and %.2f%n", 123, 45.678);

Stream 사용 예시

파일

1
2
3
4
5
6
7
8
9
10
11
try (FileInputStream fis = new FileInputStream("input.dat");
     FileOutputStream fos = new FileOutputStream("output.dat")
) {

    int data;
    while ((data = fis.read()) != -1) {
        fos.write(data); // 파일에 데이터 복사
    }
} catch (IOException e) {
    e.printStackTrace();
}
1
2
3
4
5
6
7
8
9
10
try (FileReader fr = new FileReader("input.txt");
     FileWriter fw = new FileWriter("output.txt"))
{
    int data;
    while ((data = fr.read()) != -1) {
        fw.write(data);
    }
} catch (IOException e) {
    e.printStackTrace();
}
1
2
3
4
5
6
7
8
9
10
11
try (BufferedReader br = new BufferedReader(new FileReader("input.txt"));
     BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))
) {
      String line;
      while ((line = br.readLine()) != null) {
          bw.write(line);
          bw.newLine();
      }
  } catch (IOException e) {
      e.printStackTrace();
  }

콘솔

1
2
3
4
5
6
7
8
9
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
PrintStream ps = System.out;
ps.println("이름을 입력하세요: ");
try {
    String name = reader.readLine();
    ps.println("입력하신 이름은: " + name);
} catch (IOException e) {
    e.printStackTrace();
}

그 외

그 외에도 InputStream, OutputStream의 구현체들이 많이 있습니다.

또한 InputStream, OutputStream의 구현체를 직접 만들어서 사용할 수도 있습니다.

아래는 SocketInputStream/SocketOutputStream의 사용 예시입니다.

(이 둘의 경우 java.io가 아닌 java.net 패키지의 클래스입니다.)

1
2
3
4
5
6
7
8
9
10
11
try (Socket socket = serverSocket.accept();
    SocketInputStream sis = socket.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(sis)));

    SocketOutputStream sos = socket.getOutputStream();
    PrintWriter writer = new PrintWriter(sos)) {

    String clientMessage = reader.readLine();
    System.out.println("클라이언트로부터 받은 메시지: " + clientMessage);
    writer.println("서버에서 응답: " + clientMessage);
}

정리

I/O 클래스입출력 위치입출력 단위비고
InputStream Byte추상클래스
OutputStream Byte추상클래스
Reader String추상클래스
Writer String추상클래스
InputStreamReader String보조 Reader
OutputStreamWriter String보조 Writer
BufferedReader String보조 Reader
BufferedWriter String보조 Writer
PrintWriter String보조 Writer
FileReaderFileString 
FileWriterFileString 
FileInputStreamFileByte 
FileOutputStreamFileByte 
FilterOutputStream  보조 스트림들의 슈퍼 클래스 (InputStream/OutputStream 한정)
DataInputStream Data보조 스트림
DataOutputStream Data보조 스트림
BufferedInputStream Byte보조 스트림
BufferedOutputStream Byte보조 스트림
PrintStream Byte보조 스트림
This post is licensed under CC BY 4.0 by the author.

Trending Tags