[Java] java.nio 사용법 | Path, Files, FileChannel 예제 모음

2025. 5. 30. 01:39·공부/☕Java

✅ 1. java.nio 패키지

  • NIO(New Input Output)는 기존 java.io 패키지를 개선한 새로운 입출력 패키지이다.
  • JDK 7부터는 파일 I/O를 개선한 NIO2도 등장을 함( 이때 java.nio.file 패키지가 등장함 )
  • java.nio.file, java.nio.channels, java.nio.charset 등이 있음
  • File 클래스보다 다양한 기능을 제공하는 Path 클래스를 제공함. java.nio.file 안에 Path 클래스가 있음.
  • Files 클래스를 제공하며, 파일/디렉터리의 조작, 파일의 읽기/쓰기 기능을 제공함
  • 파일 입출력 모두 가능한 FileChannel 클래스가 있음 ( 버퍼링 기능, 멀티스레드에 안전함 )
  • 입출력이 기존에는 구분이 되는 경향이 있었지만, FileChannel 클래스에서는 입출력 동시에 수행이 가능한 클래스
  • 비동기식 파일 입출력을 위한 AsynchronousFileChannel 클래스를 제공함 ( non-blocking 방식 파일 입출력 )

✅ 2. Path 인터페이스

import java.nio.file.*;
import java.io.IOException;

public class SimpleNioExample {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("hello.txt");                    // 파일 경로 생성

        Files.writeString(path, "안녕하세요!");                  // 파일에 문자열 쓰기
        String text = Files.readString(path);                 // 파일에서 문자열 읽기

        System.out.println("읽은 내용: " + text);              // 출력: 안녕하세요!

        Files.deleteIfExists(path);                           // 파일 삭제
    }
}
  • java.nio.file 패키지에 존재하며 java.io.File 클래스를 대체하는 인터페이스로 볼 수 있음.
  • 파일시스템에 존재하는 파일이나 디렉터리에 해당하는 경로를 표현함 ( 절대 경로, 상대 경로로 표현됨 )
  • 경로의 생성, 경로의 비교, 경로 정보 추출, 경로 요소 조작 기능 등을 제공함.
  • java.nio.file.Files 클래스가 실제 파일의 대한 생성, 읽기, 쓰기, 복사, 이동 등의 작업이 가능한 클래스임.
  • 즉, InputStream, OutputStream 등을 내부적으로 활용한다고 볼 수 있음.
  • 해당 Files 클래스에 Path 객체의 정보를 토대로 가능한 작업임. 즉, Path 객체가 인자로 제공이 되어야 함.
  • 그리고, 내부적으로 InputStream 등을 활용하고 있어, nio는 기존의 io패키지를 확장한 개념이라고 볼 수 있음.


✅ 3. FileSystem 클래스 & FileStore 클래스

(1) FileSystem

import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.io.IOException;

public class DiskInfoExample {
    public static void main(String[] args) throws Exception {
        FileSystem fs = FileSystems.getDefault();

        for (FileStore store : fs.getFileStores()) {
            System.out.println("드라이브 이름 : " + store.name());
            System.out.println("파일시스템 : " + store.type());
            System.out.println("전체 공간: " + store.getTotalSpace() + " bytes");
            System.out.println("사용 중인 공간: " + (stroe.getTotalSpace() - store.getUsableSpace()) + " bytes");
        }
    }
}
  • FileSystem은 파일 시스템에 대한 인터페이스를 제공함
  • FileSystems.getDefault()은 기본 파일 시스템을 리턴을 해준다.
  • lterable <FileStore> getFileStores() 호출 하면, FileStore 구현체를 리턴함. 운영체제에 맞는 구현체임.
  • FileSystem 클래스에서 WatchService new WatchService() 객체를 리턴 받을 수 있음.
  • 현재 운영체제에서 사용하는 파일 시스템에 대한 정보를 제공하고, 파일과 디렉토리 접근 방법을 제어함.
  • 즉, 운영체제마다 다른 구현 클래스를 가지고 있고, Window용 JRE에는 WindowsFileSystem과 같은 구현이있음.
  • 주요 역할: 경로(Path) 객체 생성, 파일 시스템의 루트 디렉토리 목록 조회 등이 있음.

(2) FileStore

  • 파일 시스템 내에서 실제 스토리지 장치(디스크 파티션, 네트워크 드라이브 등) 하나를 추상화한 클래스임.
  • 저장 장치의 이름, 총 공간, 사용 가능 공간, 파일 시스템 타입 등의 정보를 제공함.
  • 즉, 운영체제에 따라 이것도 다르다는 것임. FileStroe도 운영체제 마다 구현 클래스를 다르게 제공함.


✅ 4. Files 클래스

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.IOException;

public class FilesPathExample {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("example.txt");

        if (Files.exists(path)) {
            String firstLine = Files.readAllLines(path).get(0);
            System.out.println("First line: " + firstLine);
        } else {
            System.out.println("File does not exist.");
        }
    }
}
  • 파일 조작 기능을 제공하는 static 메소드를 제공한다.
  • 메소드는 Path 객체로 인자로 가지고 작업을 함.
  • 쉽게말해, 파일 입출력 I/O 기능을 제공하는 클래스를 의미하며, Path 객체의 인자를 가지고 있어야 가능함.

(1) 주요 메서드


✅ 5. java.nio.file 정리하면..

  • 정리하면, Path를 이용하려면 운영체제의 파일 정보를 알 수 있는 FileSystem 클래스의 구현체를 통해 내부적으로 알 수 있으며, Path 정보 즉, 해당 폴더의 경로를 통해 파일의 정보를 알 수 있으며, 그리고 Path 객체를 Files에 줌으로써, Files의 파일의 대한 입출력 즉, I/O가 가능해진다는 의미이다.

✅ 6. 버퍼

  • 버퍼는 데이터를 임시로 저장하는 메모리 공간을 의미하며, 주로 I/O 작업에서 데이터 처리 속도를 맞추기 위해 사용됨.
  • 쉽게말해, CPU는 입출력 말고도 많은 작업을 처리를 함. 이때, I/O 과정에서 입력이 들어오면 입력이 느리다고 가정하면 CPU는 입력을 다 기다려야 하는 문제가 발생함. 이때, 버퍼를 이용하면 입력과정에서 버퍼에 임시 저장을 해두고, CPU는 그 사이에 다른 일을 처리하는 느낌임. 그리고 입력이 끝나면 버퍼에서 입력을 받아 출력을 바로 해주는 방식
< 버퍼 사용 o >
[사람 입력] →→→ [버퍼] →→→ [자바 프로그램]
  (느림)     (임시 저장)       (빠름)
        
< 버퍼 사용 x >
[사람 입력] →→→ [자바 프로그램]
  → 느려서 자바가 계속 기다려야 함
  • 버퍼를 사용하면 지연 현상을 방지할 수 있음
  • 프로그램은 버퍼로부터 데이터를 읽음(입력)
  • 프로그램은 버퍼로 데이터를 출력함(출력)

✅ 7. Buffer 클래스

import java.nio.ByteBuffer;

public class ByteBufferExample {
    public static void main(String[] args) {
        // 1. 버퍼 생성 (용량 10바이트)
        ByteBuffer buffer = ByteBuffer.allocate(10);

        // 2. 데이터 쓰기 (put)
        buffer.put((byte) 10);
        buffer.put((byte) 20);
        buffer.put((byte) 30);

        // 3. 읽기 전에 버퍼를 '읽기 모드'로 전환 (flip)
        buffer.flip();

        // 4. 데이터 읽기 (get)
        while (buffer.hasRemaining()) {
            byte b = buffer.get();
            System.out.println("읽은 값: " + b);
        }
    }
}
  • 버퍼는 기본형 값을 저장하는 데이터 보관소를 의미하며, 채널 입출력에 사용되며 버퍼 단위로 입출력할 수 있음.
  • 기본 Stream IO는 1바이트 또는 1문자씩 입출력을 하는데, Channel IO는 버퍼 단위로 입출력을 함.
  • Buffer는 추상 클래스로 java.nio 패키지에 존재함 ( 자식 클래스에서 구현해야 할 공통의 메소드를 선언함 )
  • 실제 사용을 위해 boolean을 제외한 모든 기본형에 대해 Buffer의 서브 클래스가 존재함
  • ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer
  • 가장 일반적인건 ByteBuffer클래스임.

(1) Buffer 클래스 생성 방법 종류

// 힙 메모리에 버퍼 생성 (자바 내부 메모리)
ByteBuffer buffer = ByteBuffer.allocate(1024);

// 다이렉트 메모리에 버퍼 생성 (OS 네이티브 메모리)
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);

// 기존 바이트 배열을 감싸서 버퍼로 사용
byte[] data = new byte[10];
ByteBuffer buffer = ByteBuffer.wrap(data);

 

(2) Buffer 클래스 내부적인 4가지 주요 속성

  • 클래스 내부 상태값 즉, 필드의 값을 의미하며, 버퍼 객체가 자체적으로 관리하는 상태 정보이다.
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.capacity() // 10
buffer.position() // 0
buffer.limit()    // 10
  • 이런식으로 필드값의 담기게 됨

(3) Buffer 클래스 주요 메서드


✅ 8. FileChannel 클래스

try (FileChannel channel = FileChannel.open(Paths.get("data.txt"), StandardOpenOption.READ)) {
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    channel.read(buffer);
    buffer.flip();
    while (buffer.hasRemaining()) {
        System.out.print((char) buffer.get());
    }
}
  • java.io 패키지의 파일 관련 입출력 스트림을 대체함.
  • java.nio.channels 패키지에 존재함.
  • 파일에 대한 읽기와 쓰기를 모두 제공함.
  • 멀티 스레드 환경에서도 안전하게 사용할 수 있음.
  • FileInputStream, FileOutputStream 보다 효율적으로 파일을 다룰 수 있도록 설계가 되어있음.
  • FileChannel은 Java에서 대용량 파일 처리와 메모리 매핑을 위한 효율적인 API.
  • ByteBuffer와 함께 사용되며, 기존 스트림보다 훨씬 저수준 I/O 제어가 가능함.
  • 주로 파일 복사, 로그 처리, 대용량 바이너리 데이터 처리 등에 많이 사용됨.

(1) 객체 생성 방법

// 읽기 전용
FileChannel channel = FileChannel.open(Paths.get("example.txt"), StandardOpenOption.READ);

// 읽기 및 쓰기
FileChannel channel = FileChannel.open(Paths.get("example.txt"), StandardOpenOption.READ, StandardOpenOption.WRITE);

 

(2) 주요 메서드

 

(3) FileChannel 클래스 사용 예제

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

public class FileChannelReadExample {
    public static void main(String[] args) throws Exception { // JVM에게 예외 위임
        Path path = Path.of("example.txt"); // 읽을 파일 경로

        try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ)) {
            ByteBuffer buffer = ByteBuffer.allocate(1024); // 버퍼 생성

            int bytesRead = fileChannel.read(buffer);

            while (bytesRead != -1) {
                buffer.flip(); // 더 이상의 작업이 없고 읽기 작업만 있다면 그때 쓰는 메서드

                while (buffer.hasRemaining()) {
                    System.out.print((char) buffer.get());
                }

                buffer.clear();
                bytesRead = fileChannel.read(buffer);
            }
        }
    }
}

 

(4) 정리

  • 결론은 FileChannel은 java.nio.file.Path와 java.nio.file.Files 클래스를 활용하여, 더 정밀하고 효율적인 파일 입출력을 가능하게 만든 고급 파일 접근 도구다.
  • java.io.File 기반이 아닌, NIO 기반의 Path/Files를 활용
  • 입출력뿐 아니라 랜덤 접근, 메모리 매핑, 고성능 복사 등도 가능
  • 스트림보다 더 정밀하고 낮은 수준의 제어 가능
  • 읽기, 쓰기 둘 다 가능하므로, Input Output이 나뉘지 않음 클래스자체는..

✅ 9. WatchService 인터페이스

public class WatchTest {
    public static void main(String[] args) throws Exception {
        Path dir = Paths.get("watched"); // 감시할 폴더 (프로젝트 내부)
        WatchService watchService = FileSystems.getDefault().newWatchService();
        // watchService에 이벤트 감시 대상으로 등록
        // ENTRY_CREATE: 파일 또는 디렉토리 생성 이벤트 감지
        // ENTRY_DELETE: 삭제 이벤트 감지 MODIFY: 수정 이벤트감지
        dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);

        System.out.println("Watching folder: " + dir);

        WatchKey key = watchService.take(); // 이벤트 기다리기 (한 번만 감지)
        for (WatchEvent<?> event : key.pollEvents()) {
            System.out.println("Event: " + event.kind() + ", File: " + event.context());
        }
        key.reset();
    }
}
  • java.nio.file 패키지에서 제공하는 파일 시스템의 변경 사항을 감지하는 인터페이스이다.
  • 즉, 디렉토리 내 파일의 생성, 삭제, 수정 같은 이벤트를 실시간으로 감지할 수 있게 도와주는 API이다.
  • 이 기능을 통해 플링 없이도 파일 시스템을 감시하는 이벤트 기반 처리가 가능함.
  • 디렉터리를 표현하는 Path 객체의 변화를 감지
  • 디렉터리 내의 파일 또는 서브 디렉터리의 생성, 삭제, 수정에 대한 이벤트가 발생함을 감지한다는 의미임.
  • 위의 코드는 이벤트가 발생할 때까지 블로킹 상태로 대기를 함. (  WatchKey key = watchService.take(); )
  • 이벤트가 감지되면 WatchKey를 반환
  • 즉, 이벤트 발생 전까지 프로그램이 멈춰서 기다리게 됨. ( 결론은 딱 한 번의 이벤트 감지 코드임. )
  • WatchKey는 어떤 디렉토리에서 어떤 이벤트들이 발생했는지를 담고 있는 열쇠로 볼 수 있음.
  • 리턴을 하면서 어떤 디렉토리, 어떤 이벤트가 발생했는지를 담아서 리턴해줌으로써 알 수 있게 됨.
  • 또한, key.pollEvents() 메서드를 이용하면, 이벤트 하나하나에 대해서 상세히 리스트로 받을 수 있음
  • 이벤트를 계속 진행하기 위해서는 boolean valid = key.reset(); 을 해 줄 수 있음.

정리하면

  • take() 메서드는 WatchService가 이벤트가 발생할 때까지 대기하는 블로킹 메서드입니다. register()에 명시한 이벤트(생성, 삭제, 수정 등) 중 하나라도 발생하면, 해당 이벤트들이 WatchKey에 담겨 반환됩니다. 이렇게 반환된 WatchKey를 통해 발생한 모든 이벤트 정보를 조회할 수 있습니다.
  • 그리고, key.reset() 메서드는 반드시 수행을 시켜줘야, 다음 이벤트를 감시할 수 있게됨.

'공부 > ☕Java' 카테고리의 다른 글

[Java] 자바 스트림(Stream) 개념 + 예제 총정리 📚  (2) 2025.06.03
[Java] 컬렉션 프레임워크 정리: List, Set, Map 인터페이스와 대표 구현체 총정리  (0) 2025.05.30
[Java] java.io 패키지 입출력 스트림 쉽게 이해하기  (2) 2025.05.28
[Java] java.lang 패키지 정리: Object, String, Math 클래스 총정리  (0) 2025.05.26
[Java] 자바 함수형 인터페이스와 람다식(Lambda Expression) 쉽게 배우기  (1) 2025.05.23
'공부/☕Java' 카테고리의 다른 글
  • [Java] 자바 스트림(Stream) 개념 + 예제 총정리 📚
  • [Java] 컬렉션 프레임워크 정리: List, Set, Map 인터페이스와 대표 구현체 총정리
  • [Java] java.io 패키지 입출력 스트림 쉽게 이해하기
  • [Java] java.lang 패키지 정리: Object, String, Math 클래스 총정리
junbin2
junbin2
java.lang.NullPointerException
  • junbin2
    bin's Development Diary
    junbin2
  • 전체
    오늘
    어제
    • 전체보기 (233)
      • 방송통신대학교 (87)
        • ⚙️컴퓨터의 이해 (11)
        • 💻컴퓨터과학 개론 (15)
        • 🔢자료구조 (14)
        • 🧬알고리즘 (10)
        • ⚙️운영체제 (14)
        • 🕸️이산수학 (11)
        • 🌍유비쿼터스 컴퓨팅 (11)
        • 🖥️컴퓨터과학과 (1)
      • 공부 (72)
        • 📚백엔드 공부 (6)
        • ☕Java (23)
        • 🌳Spring (13)
        • ⚙️C (12)
        • ⚡Python (15)
        • JavaScript (1)
        • 🛢️Database (0)
        • Algorithm Problem Solving (2)
      • 네트워크 (7)
        • 📜HTTP (7)
      • 스파르타코딩클럽 (64)
      • 정보 (2)
      • 정리가 필요한 글 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    알고리즘
    spring
    함수
    Java
    컴퓨터의 이해
    유비쿼터스
    파이썬
    컴퓨터과학 개론
    이산수학
    배열
    Python
    방통대
    방송통신대학교
    자바
    컴퓨터과학과
    그래프
    C언어
    자료구조
    방송대
    운영체제
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
junbin2
[Java] java.nio 사용법 | Path, Files, FileChannel 예제 모음
상단으로

티스토리툴바