[JAVA] java.nio 패키지의 활용
java.nio
- nio는 New Input Output의 약자
- 기존 java.io를 개선한 새로운 입출력 패키지
- JDK 7부터는 파일 I/O를 개선한 NIO2 등장
- java.nio와 그것의 서브 패키지 형태
- Path 인터페이스, Files, FileChannel 클래스 제공
- 비동기식 파일 입출력을 위한 AsynchronousFileChannel 클래스 제공
- non-blocking 방식 파일 입출력
Path 인터페이스
java.io.File
클래스보다 다양한 기능을 제공하는 인터페이스java.nio.file
패키지에 존재- 파일 시스템에 존재하는 파일이나 디렉터리에 해당하는 경로를 절대/상대 경로로 표현
java.nio.file.Files
클래스의 static 메소드를 이용해 Path 객체를 조작 가능- 생성, 읽기, 쓰기, 복사 ,이동 등
- Path 객체 생성 방법
Path p = Paths.get("C:\\tmp\\foo");
- 파일이나 디렉터리의 절대/상대 경로를 명시해야 함
메소드 | 설명 |
---|---|
int compareTo(Path other) | 두 경로를 비교하여 같으면 0을 반환함 |
Path getFileName() | 디렉터리 또는 파일의 이름을 Path 객체로 리턴함 |
FileSystem getFileSystem() | Path 객체를 만들어 준 FileSystem 객체를 리턴함 |
Path getName(int index) | 경로에서 index에 해당하는 이름을 Path 객체로 리턴함 |
int getNameCount() | 경로에 포함된 원소의 개수를 리턴함 |
Path getParent() | 부모 경로를 Path 객체로 리턴함 |
Path getRoot() | 루트 디렉터리를 Path 객체로 리턴함 |
Iterator | 경로에 존재하는 모든 디렉터리 또는 파일의 이름을 Iterator 객체로 리턴 |
File toFile() | Path 객체를 File 객체로 변환하여 리턴함 |
String toString() | Path 객체를 문자열로 변환하여 리턴함 |
1
2
3
4
5
6
7
8
9
10
11
12
13
Path path = Paths.get("C:\\windows\\system32\\drivers\\etc\\hosts");
System.out.println("파일 이름:" + path.getFileName());
System.out.println("상위 폴더:" + path.getParent().getFileName());
System.out.println("경로 길이:" + path.getNameCount());
for (int i = 0; i < path.getNameCount(); i++) {
System.out.print(path.getName(i) + "\\");
}
Iterator<Path> it = path.iterator();
System.out.print("\n현재 경로: ");
while (it.hasNext()) {
System.out.print(it.next().getFileName() + "\\");
}
FileSystem 클래스와 FileStore 클래스
- FilsSystem 클래스
- 파일 시스템에 대한 인터페이스 제공
FileSystems.getDefault()
: 기본 파일 시스템을 리턴함Iterable<FileStore> getFileStores()
: 하나 이상의 파일 스토어로 구성된 Iterable을 리턴함
- FileStore 클래스
- 저장소(파티션 또는 볼륨)을 표현함
name()
,type()
,getTotalSpace()
,getUnallocatedSpace()
,getUsableSpace()
등의 메소드 제공
1
2
3
4
5
6
7
8
FileSystem fs = FileSystems.getDefault();
for (FileStore store: fs.getFileStores()) {
System.out.println("드라이브 이름: " + store.name());
System.out.println("파일 시스템: " + store.type());
System.out.println("전체 공간: " + store.getTotalSpace());
System.out.println("사용 중인 공간: " + (store.getTotalSpace() - store.UnallocatedSpace()) + "bytes");
System.out.println("사용 가능한 공간: " + store.UnallocatedSpace() + "bytes");
}
Files 클래스
- 파일 조작 기능을 제공하는 static 메소드를 제공함
- 이 메소드는 Path 객체를 인자로 가짐
- 파일의 읽기와 쓰기 메소드 제공
- 파일이나 디렉터리의 검사, 생성, 삭제, 복사, 이동, 속성 관리 메소드 제공
1
2
3
4
5
6
7
8
9
10
Path path = Paths.get("C:\\Java");
DirectoryStream<Path> ds = Files.newDirectoryStream(path);
for (Path p: ds) {
if (Files.isDirectory(p)) {
System.out.println("디렉터리: " + p.getFileName());
} else {
System.out.println("파일: " + p.getFileName());
System.out.println("파일 사이즈: " + Files.size(p));
}
}
버퍼
- 데이터가 입출력될 때 발생할 수 있는 지연을 방지하는 역할
- 프로그램은 버퍼로부터 데이터를 입력받거나 출력받음
- 기본형 값을 저장하는 데이터 보관소
- 채널 입출력에 사용되며 버퍼 단위로 입출력 가능
- Buffer는 추상 클래스로 java.nio 패키지에 존재함
- boolean을 제외한 모든 기본형에 대해 Buffer의 서브 클래스가 존재함
- ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer …
1
2
3
4
// 버퍼의 생성 방법
Buffer buffer = ByteBuffer.allocate(1024*1024);
byte[] barray = new byte[100];
Buffer buffer2 = ByteBuffer.wrap(barray);
메소드 | 설명 |
---|---|
Buffer mark() | mark를 position의 값으로 설정 |
Buffer reset() | position을 mark의 값으로 설정 |
Buffer rewind() | position을 0으로 바꾸고 mark를 삭제함 처음부터 다시 읽기를 준비하는 것 |
Buffer filp() | limit를 position 값으로 설정하고 position은 0으로 변경함. 버퍼에 쓰기를 끝내고 버퍼 읽기를 준비하는 것 |
Buffer clear() | 버퍼를 초기 상태로 돌림 새로운 쓰기를 준비하는 것 |
int capacity() | 현재 capacity 값을 리턴 |
int position() | 현재 position 값을 리턴 |
int limit() | 현재 limit 값을 리턴 |
버퍼의 속성
0 <= mark <= position <= limit <= capacity
- capacity: 버퍼의 크기(데이터의 개수). 생성될 때 정해짐
- position: 읽기나 쓰기가 적용되는 위치
- limit: 읽거나 쓸 수 없는 최초 위치
- mark: reset 되었을 때 position이 가리킬 위치
버퍼 읽기와 쓰기
- Buffer의 서브 클래스에서 제공
- 상대적 읽기/쓰기 메소드
- 현재 position의 위치에서 읽기 또는 쓰기를 수행하며 읽거나 쓴 요소만큼 position 값이 증가함
byte get()
,ByteBuffer get(byte[])
ByteBuffer put()
,ByteBuffer put(byte[])
- 절대적 읽기/쓰기 메소드
- 읽거나 쓸 위치를 매개변수 index로 지정
- position 값에 영향을 주지 않음
byte get(int index)
ByteBuffer put(int index, byte b)
FileChannel 클래스
- java.io 패키지의 파일 관련 입출력 스트림을 대체하기 위한 클래스
java.nio.channels
패키지에 존재- 파일에 대한 읽기와 쓰기를 제공
- 멀티스레드 환경에서도 안전하게 사용할 수 있음
- 객체 생성 방법
FileChannel.open(Path path, OpenOption ... options)
- 옵션은 StandardOpenOption.READ, CREATE, WRITE, APPEND 등
- FileInputStream, FileOutputStream 또는 RandomAccessFile 객체에서
getChannel()
메소드로 생성 가능
- 읽기/쓰기 메소드
int read(ByteBuffer dst)
int write(ByteBuffer src)
WatchService 인터페이스
- 어떤 대상을 정한 후 변화나 이벤트가 생기는 것을 감시(watch)하는 인터페이스
java.nio.file
패키지에 존재- 감시 대상은 Watchable 객체로,
register()
메소드를 사용하여 WatchService 객체에 감시 대상으로 등록함 - 디렉터리를 표현하는 Path 객체의 생성, 삭제, 수정 등의 변화를 감지
감시 절차
(1) WatchService 객체 생성
1
WatchService ws = FileSystems.getDefault().newWatchService();
(2) 감시 대상 디렉터리를 WatchService에 등록
1
2
3
4
Path path = Paths.get("c:\\java\\temp");
path.register(ws, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY);
(3) WatchService는 take()
메소드를 호출하여 감시함
1
2
3
4
5
6
7
WatchKey key = ws.take();
for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind k = event.kind(); // 이벤트 종류
Path p = (Path) event.context(); // 파일 이름
}
boolean valid key.reset(); // 계속 감시하기 위해 리셋
- 이벤트가 발생하면
take()
가 리턴하는 WatchKey 객체를 이용하여 이벤트를 처리 - WatchKey는 감시 상태, 감시 대상 디렉터리, 이벤트 정보를 가짐
pollEvents()
를 호출하여 WatchEvent 객체를 얻고 어떤 변화가 생겼는지 알 수 있음
예제: WatchService 인터페이스 이용하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
WatchService ws;
ws = FileSystems.getDefault().newWatchService();
Path path = Paths.get("c:\\java\\temp");
path.register(ws, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY);
while (true) {
WatchKey key = ws.take();
for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind k = event.kind();
Path p = (Path) event.context();
if (k == StandardWatchEventKinds.ENTRY_CREATE) {
System.out.println("File: " + p.getFileName() + " is created.");
} else if (k == StandardWatchEventKinds.ENTRY_DELETE) {
System.out.println("File: " + p.getFileName() + " is deleted.");
}
}
boolean valid = key.reset();
if (!valid) break;
}
This post is licensed under CC BY 4.0 by the author.