자바 1.4에서 등장한 java.nio
는 데이터, 파일 시스템, 파일을 읽고 쓰는 읽는 향상된 기능을 제공함으로써 전통적인 IO Library를 대체하기 위한 자바 API이다.
nio는 non-blocking, memory-mapped, file channels같은 효과적이고 유연한 IO 요청을 제공한다.
Path
클래스는 자바 7에서 추가된 java.nio.file
패키지에 속한 인터페이스이다.
Path는 OS에 독립적으로 파일, 디렉토리의 경로
를 표현하고 다룰 수 있는 방법을 제공한다.
Path를 통해, 파일, 디렉토리 옮기기, 복사, 삭제, 읽기, 쓰기 등의 작업을 수행할 수 있다.
뿐만 아니라, 파일 시스템과 소통할 수 있는 방법을 제공하므로, 디렉토리 생성, 파일 존재 여부 확인, 정보 불러오기 등의 작업을 수행할 수 있다.
Paths
클래스는 Path를 다룰 수 있는 여러 메서드를 제공한다.
Paths 또한 java.nio.file
패키지에 속해있다.
중요한 점은, Path는 단순히 경로
정보를 캡슐화한 것이다. 파일의 존재 여부는 상관 없다.
Path filePath1 = Paths.get("example.txt"); // file
Path filePath2 = Paths.get("example_dir/example.txt"); // file
Path dirPath= Paths.get("example_dir"); // directory
Path dirPath2= Paths.get("./parent/child"); // directory
Path noPath = Paths.get("not_existing_file_name.txt"); // 파일의 존재 여부와는 상관없다.
String fileName = filePath2.getFileName(); // example.text
String fileName2 = dirPath2.getFileName(); // child
File file = filePath1.toFile(); // 경로에 위치한 파일을 반환
Paths
를 통해 절대 경로, 상대 경로 두 방법으로 쉽게 파일에 접근할 수 있다.
// 상대 경로
Path relativeFilePath = Paths.get("relative/path/to/file.txt");
// src/main/java/.../relative/path/to/file.txt
// 절대 경로
Path absoluteFilePath = Paths.get("/root-directory/path/to/file.txt");
// /root-directory/path/to/file.txt
절대 경로를 사용할 때, 경로의 시작점(기준점)은 파일 시스템의 root directory이다.
다른 말로, 절대 경로는 항상 파일 시스템 계층의 최상위 레벨을 표현하기 위해 forward slash("/")
로 시작한다.
UNIX기반의 시스템에서, root directory는 single forward slash ("/")
로 표현되고, 모든 다른 디렉토리들과 파일들은 file system hierarchy 아래에 위치한다.
예를 들어, 절대 경로 "/home/user/documents/file.txt"
은 root directory에서 시작해서, "file.txt"
파일에 도달하기 전에 "home"
, "user"
, "documents"
디렉토리를 거친다.
상대경로는 프로젝트 루트에서 시작한다.
File
은 java.io
에, Files
는 java.nio
에 속한 클래스이다.
File
은 파일 시스템에서의 파일과 디렉토리에 대한 representation을 제공한다.
Files
는 파일 시스템을 통해, 파일을 다루는 여러 유틸리티 메서드를 제공한다.
Files
는 File
과 달리, 주로 Path
객체를 사용해 메서드를 사용한다.
파일 읽어오기
File file = new File("test.txt");
// 존재하므로 true
file.canRead();
File noFile = new File("no.txt");
// 존재하지 않으므로 false
noFile.canRead();
---------------------------------------------
파일 생성
try {
noFile.createNewFile();
Files.createNewFile(Paths.get("test.txt"));
} catch (IOException e) {}
---------------------------------------------
파일명 변경
File from = new File("from.txt");
File to = Files.get(Paths.get("to.txt"));
// from.txt -> to.txt
from.renameTo(to);
// Files로 파일명 변경하기
Path oldPath = Paths.get("from.txt");
Path newPath = Paths.get("to.txt");
Files.move(oldPath, newPath, StandardCopyOption.REPLACE_EXISTING);
---------------------------------------------
파일 쓰기
File file = new File("test.txt");
FileOutputStream fos = new FileOutputStream(file);
fos.write("hello worlds".getBytes());
fos.close(); // or fos.flush()
Files.write(Paths.get("test.txt"), "hello worlds".getBytes());
---------------------------------------------
파일 읽기
File file = new File("test.txt");
FileInputStream fis = new FileInputStream(file);
byte[] data = new byte[(int) file.length()];
fis.read(data);
fis.close();
String text = new String(data, "UTF-8");
byte[] data = Files.readAllBytes(Paths.get("test.txt"));
String text = new String(data, "UTF-8");
---------------------------------------------
EX) 여러 방법으로 파일 다루기
String rawPath = "src/main/resources/templates";
Path path = Paths.get(rawPath);
try {
Stream<Path> list = Files.list(path); // 특정 경로에 위치한 파일들
list.forEach(p -> {
System.out.println(Files.isDirectory(p)); // 디렉토리인가
System.out.println(Files.isRegularFile(p)); // 파일인가
})
} catch (IOException e) {}