JAVA

자바 고급 입출력 (NIO와 직렬화)

EunaSon 2025. 3. 6. 06:30

1. 기존 IO vs NIO 비교

자바에서는 기존 java.io 패키지와 새로운 java.nio 패키지를 이용해 입출력을 처리할 수 있다. 각각의 차이점과 사용처를 이해하면 적절한 방법을 선택하는 데 도움이 된다.

비교 항목 기존 IO (java.io) NIO (java.nio)
데이터 처리 방식 스트림(Stream) 기반 버퍼(Buffer) 기반
입출력 방식 블로킹(Blocking) 방식 논블로킹(Non-blocking) 방식
성능 작은 데이터 처리에 적합 대량 데이터 처리에 유리
주요 클래스 InputStream, OutputStream, Reader, Writer ByteBuffer, CharBuffer, FileChannel, SocketChannel
사용 예시 파일 읽기/쓰기, 간단한 콘솔 입력 네트워크 서버, 대용량 파일 처리

2. 자바 NIO(New IO)란?

자바 NIO는 기존의 java.io 패키지 기반 입출력보다 더 빠르고 유연한 입출력 처리를 제공하는 API이다. NIO는 채널(Channel), 버퍼(Buffer), 비동기 입출력(Asynchronous IO) 등의 개념을 기반으로 한다.

2.1 주요 개념

  • 채널 (Channel): NIO에서 데이터를 읽고 쓰는 핵심 요소로, 기존 IO의 스트림(Stream)과 비슷하지만 더 강력한 기능을 제공한다. 스트림이 한 방향으로만 데이터를 처리하는 것과 달리, 채널은 양방향 입출력을 지원한다. 대표적인 채널 클래스에는 FileChannel, SocketChannel, ServerSocketChannel 등이 있다/

* 양방향 입출력이란?

양방향 입출력(Bidirectional I/O)은 한 개의 스트림이나 채널을 통해 데이터를 읽고 쓰는 것이 모두 가능한 방식을 의미한다. 기존 IO에서는 입력 스트림(InputStream)과 출력 스트림(OutputStream)이 분리되어 있지만, NIO의 Channel을 사용하면 하나의 채널을 통해 동시에 읽기와 쓰기가 가능하다. 이 방식은 네트워크 통신 및 파일 처리를 더욱 유연하게 만들어준다.

  • 버퍼 (Buffer): 데이터를 임시로 저장하는 메모리 공간으로, 입출력 성능을 향상시키는 데 사용된다.
  • 셀렉터 (Selector): 다중 채널을 효율적으로 관리하는 역할을 하며, 단일 스레드에서 여러 개의 채널을 모니터링할 수 있어 네트워크 서버 개발에 유용하다.

2.2 FileChannel을 이용한 파일 읽기

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

public class NIOFileReadExample {
    public static void main(String[] args) {
        Path path = Path.of("example.txt");
        
        try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ)) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int bytesRead;
            
            while ((bytesRead = fileChannel.read(buffer)) > 0) {
                buffer.flip();
                while (buffer.hasRemaining()) {
                    System.out.print((char) buffer.get());
                }
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3. 직렬화(Serialization)와 역직렬화(Deserialization)

자바에서 객체를 파일이나 네트워크를 통해 저장하거나 전송할 때 **직렬화(Serialization)**를 사용한다. 직렬화는 객체를 바이트 스트림으로 변환하는 과정이며, **역직렬화(Deserialization)**는 다시 객체로 복원하는 과정이다.

3.1 직렬화 개념과 필요성

직렬화는 객체를 전송하거나 저장하기 위해 이진 데이터 형태로 변환하는 과정이다. 직렬화된 객체는 파일 시스템에 저장되거나 네트워크를 통해 전송될 수 있다. 대표적인 사용 사례는 다음과 같다.

  • 객체를 파일에 저장할 때: 프로그램 실행 중 생성된 객체를 저장하고, 이후 다시 불러와 사용할 수 있다.
  • 네트워크 통신에서 데이터 전송: 클라이언트와 서버 간 객체 데이터를 주고받을 때 직렬화가 필수적이다.
  • 캐싱 및 데이터베이스 저장: 객체를 직렬화하여 캐싱 시스템에 저장하면 빠르게 복원할 수 있다.

3.2 직렬화 구현 방법

자바에서는 Serializable 인터페이스를 구현하여 직렬화를 지원한다.

import java.io.*;

class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    String name;
    int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

3.3 직렬화와 역직렬화 예제

import java.io.*;

public class SerializationExample {
    public static void main(String[] args) {
        Person person = new Person("Alice", 30);
        String filename = "person.ser";

        // 직렬화
        try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename))) {
            out.writeObject(person);
            System.out.println("직렬화 완료");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 역직렬화
        try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename))) {
            Person deserializedPerson = (Person) in.readObject();
            System.out.println("역직렬화된 객체: " + deserializedPerson.name + ", " + deserializedPerson.age);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

4. 마무리

이번 글에서는 자바의 고급 입출력 기법인 NIO와 직렬화에 대해 살펴보았다.

  • 기존 IO vs NIO 비교를 통해 각각의 특징과 장단점을 파악했다.
  • 채널, 버퍼, 셀렉터를 활용한 NIO의 핵심 개념을 설명했다.
  • 파일 채널을 활용한 입출력 예제를 살펴보았다.
  • 직렬화와 역직렬화 개념을 학습하고, 실제로 객체를 저장하고 불러오는 과정을 코드로 확인했다.

NIO와 직렬화는 대규모 데이터 처리 및 네트워크 통신에서 필수적인 개념이므로, 다양한 예제와 실습을 통해 익히는 것이 중요하다. 앞으로도 다양한 입출력 방식과 최적화 기법을 활용하여 효율적인 프로그램을 작성할 수 있도록 연습하자.