티스토리 뷰
목표
자바의 Input과 Output에 대해 학습하기
스터디 목차
- 스트림 (Stream) / 버퍼 (Buffer) / 채널 (Channel) 기반의 I/O
- InputStream과 OutputStream
- Byte와 Character 스트림
- 표준 스트림 (System.in, System.out, System.err)
- 파일 읽고 쓰기
1. 스트림 (Stream) / 버퍼 (Buffer) / 채널 (Channel) 기반의 I/O
I/O란?
input과 output의 약자로 입력과 출력을 나타낸다. 즉, 컴퓨터 내부 또는 외부와의 장치와 프로그램간의 데이터를 주고 받는 것을 말한다.
스트림
스트림이란 연속적인 데이터의 흐름을 물에 비유해서 붙여진 이름인데, 여러 가지로 유사한 점이 많다. 물이 한쪽 방향으로만 흐르는 것과 같이 스트림은 단방향통신만 가능하기 때문에 하나의 스트림으로 입력과 출력을 동시에 처리가 불가하다. 그래서 입력과 출력을 동시에 하려면 입력스트림과 출력스트림을 각각 만들어 총 2개의 스트림이 필요하다.
NIO(new IO)
기존의 자바 IO API를 대체하기 위해 자바 1.4부터 도입이 되었다. 기존 IO API에서는 byte streams character streams 사용했지만, NIO에서는 channels(채널)과 buffers(버퍼)를 사용한다.
NIO의 주요 키워드
Channels
일반적으로 NIO의 모든 IO는 채널로 시작한다. 채널데이터를 버퍼로 읽을 수 있고, 버퍼에서 채널로 데이터를 쓸 수 있다. 채널은 스트림과 유사하지만 몇가지 차이점이 존재한다.
- 채널을 통해서는 읽고 쓸 수 있지만, 스트림은 일반적으로 단방향(읽기 혹은 쓰기)으로만 가능하다.
- 채널은 비동기적 으로 읽고 쓸 수 있다.
- 채널은 항상 버퍼에서 부터 읽거나 버퍼로 쓴다.
Buffer
NIO의 버퍼는 채널과 상호작용할 때 사용된다. 커널에 의해 관리되는 시스템 메모리를 직접 사용할 수 있는 채널에 의 해 직접 read 되거나 write 될 수 있는 배열과 같은 객체
IO에서는 출력 스트림이 1바이트를 쓰면 입력 스트림이 1바이트를 읽는다. 이것 보다는 버퍼를 사용해서 복수 개의 바이트를 한꺼번에 입력받고 출력하는 것이 빠른 성능을 낸다.
Selector
셀럭터를 사용하면 하나의 스레드가 여러 채널을 처리(handle)할 수 있다. 클라이언트 하나당 쓰레드 하나를 생성해서 처리하기 때문에 쓰레드가 많이 생성될수록 급격한 성능 저하를 가졌던 단점을 개선하는 Reactor 패턴의 구현체
IO와 NIO의 차이점
구분 | IO | NIO |
입출력 방식 | 스트림 방식 | 채널 방식 |
버퍼 방식 | 넌버퍼 | 버퍼 |
비동기 방식 | 지원 안함 | 지원 |
블로킹 방식 | 블로킹 방식만 지원 | 블로킹 / 넌블로킹 모두 지원 |
2. InputStream과 OutputStream
InputStream
바이트 기반 입력 스트림의 최상위 클래스로 추상클래스 이다. 모든 바이트 기반 입력 스트림은 이 클래스를 상속받아서 만들어 진다. InputStream 클래스에는 바이트 기반 입력 스트림이 기본적으로 가져야 할 메소드들이 정의 되어 있다.
메서드 | 설명 |
read() | 입력 스트림으로부터 1바이트를 읽고 읽은 바이트를 리턴한다. |
read(byte[] b) | 입력 스트림으로부터 읽은 바이트들을 매개값으로 주어진 바이트 배열b에 저장하고 실제로 읽은 바이트 수를 리턴한다. |
read(byte[] b, int off, int len) | 입력 스트림으로부터 len개의 바이트만큼 읽고 매개값으로 주어진 바이트 배열 b[off]부터 len개까지 저장한다. 그리고 실제로 읽은 바이트 수인 len개를 리턴한다. 만약 len개를 모두 읽지 못하면 실제로 읽은 바이트 수를 리턴한다. |
close() | 사용한 시스템 자원을 반납하고 입력스트림을 닫는다. |
OutputStream
바이트 기반 출력 스트림의 최상위 클래스로 추상클래스 이다. 모든 바이트 기반 출력 스트림은 이 클래스를 상속받아서 만들어진다. OutputStream 클래스에는 바이트 기반 출력 스트림이 기본적으로 가져야 할 메소드가 정의되어 있다.
메서드 | 설명 |
write(int b) | 출력 스트림으로 부터 1바이트를 보낸다. |
write(byte[ ] b) | 출력 스트림으로부터 주어진 바이트 배열 b의 모든 바이트를 보낸다. |
write(byte[ ] b, int off, int len) | 출력 스트림으로 주어진 바이트 배열 b[off]부터 len개까지의 바이트를 보낸다. |
flush() | 버퍼에 잔류하는 모든 바이트를 출력한다. |
close() | 사용한 시스템 자원을 반납하고 출력 스트림을 닫는다. |
3. Byte와 Character 스트림
데이터를 어떤 방식으로 전달하느냐에 따라 스트림은 두가지로 나뉜다.
바이트 스트림(Byte Stream)
binary 데이터를 입출력하는 스트림이다, 이미지, 동영상 등을 송수신할 때 주로 사용한다.
- InputStream / OutputStream : byte 기반 input/output stream의 최고 조상
- ByteArrayInputStream / ByteArrayOutputStream : byte array(byte[]) 에 대한 데이터를 입출력 하는 클래스
- FileInputStream / FileOutputStream : 파일(file)에 대한 데이터를 입출력 하는 클래스
문자 스트림(Character Stream)
text 데이터를 입출력하는데 사용하는 스트림이다. HTML 문서, 텍스트 파일을 송수신할 때 주로 사용한다.
- Reader / Writer : Character 기반 input / output stream의 최고 조상
- FileReader / FileWriter : 문자 기반의 파일을 입출력 하는 클래스
4. 표준 스트림 (System.in, System.out, System.err)
자바에서 미리 정의해둔 표준 입출력 클래스, 표준 입출력은 콘솔화면에 입출력 된다고 해서 콘솔 입출력 이라고도 함
- System.in : 표준 입력용 스트림
- System.out : 표준 출력용 스트림
- System.err : 표준 오류 출력 스트림
표준 입출력 Method
메서드 | 설명 |
System.in.read() | 키보드로 입력된 값을 읽어들임, 더 이상 읽어들일 수 없으면 -1 리턴 |
System.out.write() | ( )안에 입력된 값을 화면(콘솔)에 출력, 컴퓨터가 숫자로 저장하고 있는 것을 사람이 읽을 수 있는 문자로 디코딩해서 출력 |
System.out.flush() | 출력은 버퍼에 일정 용량 이상이 쌓여야 가능한데, 버퍼를 비워서 바로 출력하도록 하는 메소드 데이터를 일정 용량 쌓아두었다가 출력하는 이유는 입출력 성능 향상을 위함 |
입출력 메소드 사용시 반드시 예외 처리를 해줘야함
5. 파일 읽고 쓰기
파일 읽기(Read)
FileReader 객체와 BufferReader 객체가 사용된다.
String fileName = "C:/test.txt" // 읽어들일 파일명
FileReader fileReader = new FileReader(fileName);
BufferedReader reader = new BufferedReader(fileReadrer);
String line = null;
while((line = reader.readLine()) != null) { // readLine() 은 한줄 단위로 읽어들임
System.out.println(line);
}
reader.close();
파일 쓰기 (Write)
FileWriter 객체와 BufferWriter 객체가 사용된다.
String fileName = "C:/test.txt" // 생성할 파일명
String str = "abc" // 작성할 문자열
FileWriter fileWriter = new FileWriter(fileName);
BufferedWriter out = new BufferedWriter(fileWriter);
out.write(str); // 쓰기
out.newLine(); // 줄바꾸기
out.close();
Reference
jongmin92.github.io/2019/03/03/Java/java-nio/
coding-factory.tistory.com/281
'Live Study' 카테고리의 다른 글
[JAVA 스터디] 15주차 과제 : 람다식 (0) | 2021.03.03 |
---|---|
[JAVA 스터디] 14주차 과제 : 제네릭 (0) | 2021.02.24 |
[JAVA 스터디] 12주차 과제 : 애노테이션 (0) | 2021.02.01 |
[JAVA 스터디] 11주차 과제 : Enum (0) | 2021.01.25 |
[JAVA 스터디] 10주차 과제 : 멀티쓰레드 프로그래밍 (0) | 2021.01.19 |