IO와 스트림(Stream)
IO란?
Input과 Output의 준말로 마우스,키보드 입력 등 프로그램을 들어오는 값을 Input 값, 모니터, 스피커 출력 등 밖으로 나가는 값을 Output값이라 한다
Stream이란?
- 스트림이란 데이터의 연속적인 흐름을 의미하는데 말 그대로 강 줄기가 흘러가듯 한 방향으로 데이터처리가 이뤄진다는 점이 있다.
- 단방향인 만큼 시작하는 점과 끝나는 점이 있는 이를 Input과 Output으로 나타낼 수 있다.
- 예를 들어 키보드를 통해 무언가를 입력하고 프로그램을 통해 모니터로 출력이 된다면 이는 곧 키보드에서 모니터까지 한 방향으로 데이터가 흘러간다고 볼 수 있다.
- 이러한 구조 때문에 입력 스트림과 출력 스트림을 각각 따로 사용해야 하며 먼저 들어온 데이터가 먼저 나가는 First in first out (FIFO) 구조를 이룬다
- 스트림은 출력 단위가 바이트 단위인 바이트기반 스트림과 출력 단위가 문자 단위인 문자 기반 스트림으로 나눠진다
바이트기반 스트림
- 바이트기반 스트림은 바이트단위로 데이터를 입출력하는 스트림이다
- 1byte씩 끊어서 읽고 출력한다
- InputStream, OutputStream 클래스가 모든 바이트기반 스트림들의 조상이 된다
- InputStream을 상속받는 스트림은 read() 추상 메서드를 구현한다
- OutputStream을 상속받는 스트림은 write() 추상 메서드를 구현한다
InputStream의 메서드
<int read()>
: 내용을 읽고 그 값을 정수로 반환하는데, 파일의 끝에 (eof) 도달하거나 스트림이 종료되면 -1을 반환한다
<int read(byte[] b)>
: 파일 내용을 한번에 모두 읽어서 배열에 저장
<int read(byte[] b, int off, int len)>
: len 길이만큼 읽어서 배열의 off 번째 위치부터 저장
OutputStream의 메서드
<void write(int b)>
: b의 하위 8비트를 출력 스트림에 적는다
<void write(byte[] b)>
: 배열 변수 b의 모든 요소들을 출력 스트림에 적는다
<void write(byte[] b, int off, int len)>
: off 위치 부터 len 개의 b의 요소를 출력 스트림에 적는다
FileInputStream/FileOutputStream
- 추상클래스인 InputStream과 OutputStream의 하위 클래스로 이들로부터 기능을 상속 받아 데이터를 읽어오고 쓰는 등의 처리를 하는 클래스다.
- 컴퓨터의 파일 시스템과 직접 연결되서 컴퓨터의 저장 장치에 저장된 파일을 다루는데 특화되어 있다
- 처리하고자 하는 파일이 존재하지 않거나 권한이 없는 경우가 있기에 반드시 try-catch 예외처리를 해야 사용 가능하다
파일 입출력을 맟니 후에는 반드시 close() 메서드를 이용해 스트림을 닫아줘야 한다 (출력스트림-입력스트림 순)
바이트 기반 보조 스트림
말 그대로 바이트 기반 스트림의 성능을 향상시키기 위해 보조해주는 역할을 하는 스트림이다. FileInputStream 같은 스트림이 할 수 없는 기능을 이용하고 코드의 가독성을 높여주기 때문에 사용한다. 데이터를 전송할 스트림을 선언하고 그 스트림을 인자로 보조 스트림의 생성자로 넣어주면 된다
InputStream계열
<BufferedInputStream>
: 여러 번 읽기 작업을 할 때, 한 번에 많은 양의 데이터를 미리 읽어 버퍼에 저장해 두었다가 필요할 때마다 버퍼에서 가져오는 방식이라 파일 시스템에 접근해야하는 횟수를 줄여 성능을 향상 시켜줌
<DataInputStream>
: 바이트 스트림을 기본형 데이터(int, double 등)로 변환하여 읽어옴
OutputStream 계열
BufferedOutputStream : 여러 번 쓰기 작업을 할 때, 데이터를 버퍼에 모아뒀다가 한번에 출력해 성능을 향상시킴
DataOutputStream : 기본형 데이터를 바이트 스트림으로 변환하여 출력함
PrintStream : print(), println() 등의 메서드를 제공하여 문자열을 편리하게 출력할 수 있도록 함
스트림의 예외 처리
우리가 주로 사용할 FileInputStream/FileOutputStream의 경우 앞서 설명했듯이 다루고자 하는 파일이 누락되거나 디스크의 공간이 부족하거나 권한이 없는 등, 처리하고자 하는 데이터(파일)에 접근이 불가능한 경우가 생길 수 있다. 그렇기 때문에 Java에서는 FileInputStream/FileOutputStream 외 다른 Stream 들을 포함해서 대부분의 경우에 throws나 try-catch 예외 처리를 강제하고있다.
public static void main(String[] args)
{
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
//
//
try {
fis = new FileInputStream("C:\\prac.txt");
bis = new BufferedInputStream(fis);
fos = new FileOutputStream("result.txt");
bos = new BufferedOutputStream(fos);
int data;
while((data = fis.read()) != -1)
{
bos.write(data);
}
bos.close();
bis.close();
fos.close();
fis.close();
}catch (Exception e) {e.printStackTrace();}
}
한 줄 정리
- IO는 Input과 Output의 준말로 값을 들여보내고 내보내는 것을 의미한다
- Stream이란 Input과 Output을 통해 데이터를 연속적으로 처리하는 개념으로, FIFO 구조를 가지며 바이트 기반과 문자 기반 스트림이 있다
- 바이트기반 스트림은 InputStream과 OutputStream으로 나눌 수 있으며 각각 read(), write() 추상 메서드를 포함한다
- read()는 내용을 읽고 내용이 없으면 -1을 반환한다
- write(int b)는 b의 하위 8비트를 출력 스트림에 적는다
- FileInputStream/FileOutputStream은 컴퓨터의 저장 장치에 저장된 파일을 다루는데 특화된 스트림이다
- 바이트 기반 보조 스트림은 기본 스트림의 성능을 향상시켜주는 역할을 한다
- 스트림 사용 시에는 반드시 예외 처리를 해주어야 하며, 사용 후 close() 메서드로 스트림을 닫아주어야 한다
- 스트림 클래스 선언 시 초기화를 null로 해주는 것이 권장된다
'Java' 카테고리의 다른 글
Java 프로그래밍 - 자바 네트워크 프로그래밍 (1) | 2024.09.26 |
---|---|
Java 프로그래밍 - 추상 메서드와 추상 클래스 (0) | 2024.09.19 |
Java 프로그래밍 - 객체와 클래스 (0) | 2024.09.09 |
Java 프로그래밍 - 반복문과 배열 (0) | 2024.09.06 |
Java 프로그래밍 - 조건문, 반복문 (1) | 2024.09.05 |