- 스트림 (Stream) / 버퍼 (Buffer) / 채널 (Channel) 기반의 I/O
- InputStream과 OutputStream
- Byte와 Character 스트림
- 표준 스트림 (System.in, System.out, System.err)
- 파일 읽고 쓰기
- 입출력은 컴퓨터 내부 또는 외부 장치와
프로그램 간에 데이터를 주고 받는 것을 말한다.- ex)
Input: 키보드로 데이터를 입력받아 /Output: System.out.println()으로 화면에 출력한다.
- ex)
import java.io.*;
public class IoTest {
public static void main(String[] args) throws FileNotFoundException {
try (
InputStream inputStream = new FileInputStream("src/io_test/abc.txt");
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream)
) {
char readChar;
while((readChar = (char)bufferedInputStream.read()) > 90) {
System.out.println(readChar);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}-
데이터를 운반하는데 사용되는 연결 통로이다. -
스트림은
단방향통신만 가능하다.- 하나의 스트림으로 입출력을 동시에 하는 것은 어렵다. = 입출력을 동시에 하기 위해서
입력스트림, 출력스트림이 별도로 필요하다.
- 하나의 스트림으로 입출력을 동시에 하는 것은 어렵다. = 입출력을 동시에 하기 위해서
-
스트림은 먼저 전송한 데이터를 먼저 반는다. 즉,
FIFO(First In, First Out)구조를 가지고 있다. -
중간에 건너뜀없이
연속적으로 데이터를 주고 받는다.
-
목적 : 스트림 기능을 보완하기 위함.
-
데이터를 입출력할 수 있는 기능은 없다. 하지만, 스트림의
기능 향상, 추가할 수 있다. -
즉, 스트림 생성하고 그 다음에 보조 스트림을 생성해서 활용한다.
-
Java.io package는
Decoration pattern을 통해 구현되었음.-
Decoration pattern: A클래스에서 B클래스를 생성자로 받아와서, B클래스에 추가적인 기능을 덧붙여서 제공하는 패턴이다.(즉, BufferedReader에 Reader를 받아와서
Reader클래스에Buffer기능을 덧붙여서 제공하는 패턴.)//BufferedReader class public class BufferedReader extends Reader { private Reader in; public BufferedReader(Reader in, int sz) { super(in); if (sz <= 0) throw new IllegalArgumentException("Buffer size <= 0"); this.in = in; cb = new char[sz]; nextChar = nChars = 0; } public BufferedReader(Reader in) { this(in, defaultCharBufferSize); } }
-
- byte, char, int 등 기본 데이터 타입을 저장할 수 있는 저장소로, 배열과 마찬가지로 제한된 크기(capacity) 에 순서대로 데이터를 저장한다.
- 채널을 통해서 소켓, 파일 등에 데이터를 전송할 때나 읽어올 때 버퍼를 사용하게 됨으로써 가비지량을 최소화 시킬 수 있게 되며, 이는 가바지 콜렉션 회수를 줄임으로써 서버의 전체 처리량을 증가시켜준다.
- 데이터를 전송하는 상호 간의 장치에서 고속의 장치와 저속의 장치 간의 속도 차이로 인해 저속의 장치가 작업을 추리하는 동안, 고속의 장치가 기다려야하는 현상을 줄여주는 기술. (kyu09님의 요약정리)
- 버퍼를 사용할 때의 장점 : OS 레벨의
시스템 콜의 횟수가 줄어들면, 입출력 횟수가 줄어들고성능이 빨라진다.
- 스트림과 달리
양방향으로 입출력이 가능한 형태.(스트림과 달리 입출력을 위한 별도의 채널을 만들 필요가 없다.) - 채널에서 데이터를 주고 받을 때 버퍼(buffer)가 사용된다.
-
java.iopackage는 stream 기반 I/O를 지원하고,java.niopackage 는 channel 기반 I/O를 지원한다. -
java.io :
blockingI/O를 기반으로 함. 입출력을 위한 메서드 호출 시,데이터를 읽거나 쓰기 전까지 해당 thread는 blocking 상태이다. -
java.nio: `non-blocking' I/O를 기반으로 함. java.io 클래스에서도 buffer를 사용할 수 있지만 java.nio 경우, ByteBuffer 클래스의 allocateDirect()메서드를 사용하면 커널 버퍼를 사용할 수 있다는 장점이 있다.(kernel buffer : OS 의 버퍼에서 JVM 내부의 버퍼로 데이터를 옮기는 작업이 필요없는 버퍼)
- 바이트 기반 입력 스트림의 최상위 추상 클래스
- 모든 바이트 기반 입력 클래스는 해당 클래스를 상속받아 사용한다.
- 버퍼, 파일, 네트워크 단에서 입력되는 데이터를 읽어오는 기능을 수행한다.
| 메서드 | 설명 |
|---|---|
| int available() | 스트림으로부터 읽어올 수 있는 데이터 크기를 반환 |
| void close() | 닫음으로써 사용하고 있던 자원을 반환 |
| void mark(int readlimit) | 현재 위치를 표시해 놓는다. 후에 reset()에 의해서 표시해놓은 위치로 다시 돌아갈 수 있다. readlimit는 되돌아갈 수 있는 byte수이다. |
| abstract int read() | 1byte를 읽어온다.(0 ~ 255사이의 값) 더 이상 읽어올 값이 없으면 -1을 반환한다. abstract 추상 메서드임으로 InputStream의 자손들은 자신의 상황에 알맞게 구현해야 한다. |
| int read(byte[] b, int off, int len) | 최대 len개의 byte를 읽어, 배열 b의 지정 위치(off)부터 저장한다. 실제로 읽어올 수 있는 데이터가 len보다 적을 수도 있다. |
| void reset() | 스트림에서의 위치를 마지막으로 mark()이 호출되었던 취치로 되돌린다. |
| long skip(long n) | 주어진 길이(n)만큼 건너뛴다. |
- 바이트 기반 출력 스트림의 최상위 추상 클래스
- 모든 바이트 기반 출력 스트림은 이 클래스를 상속받아 사용한다.
- 버퍼, 파일, 네트워크 단으로 데이터를 내보내는 기능을 수행한다.
| 메서드 | 설명 |
|---|---|
| void close() | 입력 소스를 닫음으로써 사용하고 있던 자원을 반납 |
| void flush() | 스트림의 버퍼에 있는 모든 내용을 출력 소스에 쓴다. |
| abstract void write(int b) | 주어진 값을 출력 소스에 쓴다. |
| void write(byte[] b) | 주어진 배열 b에 저장된 모든 내용을 출력 소스에 쓴다. |
| void write(byte[] b, int off, int len) | 주어진 배열 b에 저장된 내용 중에서 off번째 부터 len개 만큼만을 읽어서 출력 소스에 쓴다. |
- 문자 기반 입력 스트림의 최상위 추상 클래스
- 모든 문자 기반 스트림에서는 이 클래스를 상속받아 사용한다.
- 바이트기반의 경우, byte[]를 받는 반면, 문자 기반은
char[]배열을 사용한다. - 자바의 경우
유니코드(UTF-16)으로 자동 처리해준다.
| 메서드 | 설명 |
|---|---|
| abstract void close() | 입력 스트림을 닫음으로써 사용하고 있던 자원을 반납한다. |
| void mark(int readlimit) | 현재 위치를 표시해놓는다. 후에 reset()에 으해 표시해 놓은 위치로 다시 돌아갈 수 있다. |
| boolean markSupported() | mark()와 reset()을 지원하는지 알려준다. |
| int read() | 하나의 문자를 읽어온다. char의 범위인 0~65535범위의 정수를 반환하며, 입력 스트림의 마지막 데이터에 도달하면, -1을 반환한다. |
| int read(char[] c) | 입력 소스로 부터 매개변수로 주어진 배열 c의 크기만큼 읽어서 배열 c에 저장한다. 읽어온 데이터의 개수 또는 -1을 반환한다. |
| abstract int read(char[] c, int off, int len) | 입력 소스로 부터 최대 len개의 문자를 읽어서, 배열 c의 저장된 위치(off)부터 읽은 다음 저장한다. 읽어온 데이터 개수 또는 -1을 반환한다. |
| int read(CharBuffer target) | 입력 소스로부터 읽어서 문자버퍼(target)에 저장한다. |
| boolean ready() | 입력 소스로부터 데이터를 읽을 준비가 되어있는지 알려준다. |
| void reset() | 입력 소스에서의 위치를 마지막으로 mark()가 호출되었던 위치로 되돌린다. |
| long skip(long n) | 현재 위치에서 주어진 문자 수(n)만큼을 건너뛴다. |
- 문자 기반 출력 스트림의 최상위 추상 클래스
- 모든 문자 기반 스트림에서는 이 클래스를 상속받아 사용한다.
- 바이트기반의 경우, byte[]를 받는 반면, 문자 기반은
char[]배열을 사용한다. - 자바의 경우
유니코드(UTF-16)으로 자동 처리해준다.
| 메서드 | 설명 |
|---|---|
| Writer append(char c) | 지정된 문자를 출력소스에 출력한다. |
| Writer append(charSequence c) | 지정된 문자열(CharSequence)을 출력소스에 출력한다. |
| Writer append(CharSequence c, int start, int end) | 지정된 문자열(CharSequence)의 일부를 출력소스에 출력(CharBuffer, String, StringBuffer가 CharSequence를 구현) |
| abstract void close() | 출력 스트림을 닫음으로써 사용하고 있던 자원을 반환한다. |
| abstract void flush() | 스트림 버퍼에 있는 모든 내용을 출력 소스에 쓴다. |
| void write(int b) | 주어진 값을 출력 소스에 쓴다. |
| void write(char[] c) | 주어진 값을 출력 소스에 쓴다. |
| abstract void write(char[] c, int off, inf len) | 주어진 배열 c에 저장된 내용 중에서 off번째부터 len길이 만큼만 출력 소스에 쓴다. |
| void write(String str) | 주어진 문자열(str)을 출력 소스에 쓴다. |
| void write(String str, int off, int len) | 주어진 문자열(str)의 일부를 출력 소스에 쓴다. (off번째 문자부터 len개만큼의 문자열)\ |
public final class System {
public static final InputStream in;
public static final PrintStream out;
public static final PrintStream err;
}-
System class : 실행 시간, 환경과 관련된 속성과 메소드를 가지고 있다
-
System.in: 콘솔로 입력을 받는 표준 스트림을 가리키는 상수.-
영어를 입력하고 싶은 경으, System.in.read()를 사용해도 가능하다.int input = System.in.read(); System.out.println(input); //입력 : i -> 출력 : i //입력 : 쿠 -> 출력 : ì
-
하지만,
한글을 입력하고 싶은 경우, InputStreamReader를 사용하도록 하자!InputStreamReader inputStreamReader = new InputStreamReader(System.in); int input = inputStreamReader.read(); System.out.println(input); //입력 : 쿠퍼 -> 출력 : 쿠퍼
-
-
System.out: 콘솔로 출력하는 표준 스트림을 가리키는 상수.- ex)
System.out.println();
- ex)
-
System.err: 표준 에러 출력 장치를 가리키는 상수
-
-
파일 읽어서 콘솔에 출력
import java.io.*; public class FileIOTest { public static void main(String[] args) { String line; try (BufferedReader br = new BufferedReader(new FileReader("src/io_test/abc.txt"))) { while ((line = br.readLine()) != null) { System.out.println(line); } } catch (Exception e) { e.printStackTrace(); } } }
-
.txt파일 생성 및 내용 작성하기!
import java.io.*; public class FileIOTest { public static void main(String[] args) { File file = new File("src/io_test/cooper.txt"); try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) { bw.write("Hi, Cooper"); bw.newLine(); bw.write("Please go to home..."); bw.newLine(); bw.flush(); } catch (Exception e) { e.printStackTrace(); System.out.println("똑바로 쓰자. 진짜."); } } }
-
ssonsh님의 I/O정리 : https://www.notion.so/I-O-af9b3036338c43a8bf9fa6a521cda242
-
Java Tutorials - Byte Stream : http://www.btechsmartclass.com/java/java-byte-stream.html
-
Java Tutorials - Character Stream : http://www.btechsmartclass.com/java/java-character-stream.html


