7.5 KiB
7.5 KiB
자바 NIO (New Input/Output) 관련 클래스 및 주요 메서드 정리
자바 NIO는 기존의 java.io보다 더 빠르고 효율적인 비동기식 입출력 처리를 제공하는 API다.
NIO의 핵심 개념은 **버퍼(Buffer), 채널(Channel), 셀렉터(Selector)**이다.
1. Buffer 클래스 및 주요 메서드
| 메서드 | 설명 |
|---|---|
allocate(int capacity) |
지정된 크기의 버퍼 생성 (ByteBuffer.allocate(1024)) |
wrap(byte[] array) |
기존 배열을 감싸는 버퍼 생성 |
put(T value) |
버퍼에 데이터 저장 |
get() |
버퍼에서 데이터 읽기 |
flip() |
읽기 모드로 전환 (쓰기 → 읽기) |
clear() |
버퍼를 초기화 (데이터 삭제 X, 포인터 리셋) |
compact() |
읽지 않은 데이터를 앞으로 이동하고, 쓰기 모드로 전환 |
position() |
현재 읽기/쓰기 위치 반환 |
limit() |
읽기/쓰기 가능한 최대 위치 반환 |
remaining() |
남은 읽기/쓰기 가능 데이터 개수 반환 |
버퍼의 주요 종류:
ByteBuffer(바이트 저장)CharBuffer(문자 저장)IntBuffer,FloatBuffer등
2. Channel 인터페이스 및 주요 메서드
| 메서드 | 설명 |
|---|---|
open(Path path, OpenOption...) |
파일 채널 열기 (FileChannel.open(path)) |
read(ByteBuffer dst) |
데이터를 버퍼로 읽음 |
write(ByteBuffer src) |
버퍼의 데이터를 채널에 씀 |
close() |
채널 닫기 |
position() |
현재 위치 반환 |
size() |
파일 크기 반환 |
truncate(long size) |
파일 크기를 지정한 크기로 자름 |
force(boolean metaData) |
버퍼 내용을 강제로 디스크에 저장 |
채널의 주요 종류:
FileChannel(파일 입출력)SocketChannel(TCP 소켓 통신)ServerSocketChannel(TCP 서버 소켓)DatagramChannel(UDP 통신)
3. Selector 클래스 및 주요 메서드
| 메서드 | 설명 |
|---|---|
open() |
새로운 셀렉터 생성 |
select() |
I/O 이벤트가 발생할 때까지 대기 |
selectNow() |
즉시 이벤트 확인 (블로킹 X) |
select(timeout) |
지정된 시간 동안 대기 |
keys() |
등록된 모든 채널 반환 |
selectedKeys() |
이벤트가 발생한 채널 반환 |
wakeup() |
블로킹 상태에서 셀렉터를 깨움 |
close() |
셀렉터 닫기 |
관련 클래스:
SelectionKey.OP_READ(읽기 가능)SelectionKey.OP_WRITE(쓰기 가능)SelectionKey.OP_CONNECT(연결 가능)SelectionKey.OP_ACCEPT(새로운 연결 가능)
자바 NIO 쉽게 설명하기
NIO란 무엇인가?
NIO는 기존의 java.io보다 더 빠르고 비동기적으로 입출력을 처리할 수 있는 기술이다.
-
기존 방식 (IO)
- 데이터를 스트림(Stream) 단위로 처리
- 블로킹 방식 (데이터를 읽거나 쓸 때 작업이 끝날 때까지 대기)
- 한 번에 하나의 입출력만 가능
-
NIO 방식
- 데이터를 **버퍼(Buffer)와 채널(Channel)**을 이용해 처리
- 논블로킹 방식 (데이터를 읽거나 쓸 때 대기하지 않고 바로 진행)
- 하나의 스레드가 여러 채널을 관리 가능 (셀렉터 사용)
1. 버퍼(Buffer) 이해하기
버퍼는 데이터를 담아두는 공간이다.
IO에서는 데이터를 바로 읽고 쓰지만, NIO에서는 데이터를 버퍼에 담고 처리한다.
ByteBuffer buffer = ByteBuffer.allocate(1024); // 1KB 크기의 버퍼 생성
buffer.put("Hello NIO".getBytes()); // 데이터 쓰기
buffer.flip(); // 읽기 모드로 변경
byte[] data = new byte[buffer.remaining()];
buffer.get(data); // 데이터 읽기
System.out.println(new String(data)); // "Hello NIO"
put()→ 데이터를 버퍼에 저장flip()→ 읽기 모드로 변경get()→ 버퍼에서 데이터 읽기
2. 채널(Channel) 이해하기
채널은 데이터가 오가는 통로다.
기존의 InputStream / OutputStream 대신 파일, 소켓 등과 데이터를 주고받는 역할을 한다.
파일을 읽는 예제 (FileChannel)
Path path = Paths.get("example.txt");
FileChannel channel = FileChannel.open(path, StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer); // 파일에서 데이터를 읽어 버퍼에 저장
buffer.flip();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
System.out.println(new String(data)); // 파일 내용 출력
channel.close();
FileChannel.open()→ 파일을 열고 채널 생성read(ByteBuffer)→ 파일 데이터를 버퍼에 읽기flip()→ 읽기 모드로 변경get()→ 버퍼에서 데이터 가져오기
3. 논블로킹 소켓 (SocketChannel) 사용하기
NIO의 강점은 네트워크 프로그래밍에서 논블로킹 소켓을 사용할 수 있다는 점이다.
즉, 하나의 스레드가 여러 소켓을 동시에 처리할 수 있다.
비동기 TCP 클라이언트 예제
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false); // 논블로킹 모드 설정
socketChannel.connect(new InetSocketAddress("localhost", 8080));
while (!socketChannel.finishConnect()) {
System.out.println("연결 시도 중...");
}
ByteBuffer buffer = ByteBuffer.wrap("Hello Server".getBytes());
socketChannel.write(buffer); // 서버로 데이터 전송
socketChannel.close();
configureBlocking(false)→ 논블로킹 모드 설정connect()→ 서버에 연결write(ByteBuffer)→ 서버로 데이터 전송
4. Selector로 다중 채널 관리하기
셀렉터(Selector)를 사용하면 하나의 스레드로 여러 채널을 관리할 수 있다.
즉, 효율적인 멀티플렉싱 처리가 가능하다.
비동기 서버 예제
Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.bind(new InetSocketAddress(8080));
serverChannel.configureBlocking(false);
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
selector.select(); // I/O 이벤트 발생할 때까지 대기
for (SelectionKey key : selector.selectedKeys()) {
if (key.isAcceptable()) { // 클라이언트 연결 요청 처리
SocketChannel client = serverChannel.accept();
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) { // 데이터 읽기 처리
SocketChannel client = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
client.read(buffer);
buffer.flip();
System.out.println("Received: " + new String(buffer.array()).trim());
}
}
}
Selector.open()→ 셀렉터 생성select()→ I/O 이벤트 발생 대기register()→ 채널을 셀렉터에 등록
정리
자바 NIO는 버퍼 + 채널 + 셀렉터를 이용해
- 파일 입출력을 빠르게 처리하고
- 네트워크 소켓을 논블로킹 방식으로 다룰 수 있게 해준다.
즉, 적은 스레드로 많은 연결을 처리하는 고성능 서버를 만들 때 강력한 도구가 된다!