CodeGym /행동 /JAVA 25 SELF /File, Path, Files 클래스: 개요, 객체 생성

File, Path, Files 클래스: 개요, 객체 생성

JAVA 25 SELF
레벨 35 , 레슨 1
사용 가능

1. 클래스 File: 어떻게 시작되었나

비록 새로운 프로젝트에서 File 클래스를 사용하지 않는 편이 좋다는 것을 이미 확인했지만, 여전히 이 클래스가 쓰이는 레거시 시스템이 많습니다. 따라서 이를 이해하고 다룰 수 있어야 합니다. File 클래스는 디스크의 파일이나 디렉터리를 표현하는 옛 방식입니다. 하지만 혼동하지 마세요. File 객체는 파일 자체가 아니라 경로의 "포인터"/여권일 뿐입니다. 예를 들어, File f = new File("hello.txt"); 라는 표현은 디스크에 파일을 생성하지 않습니다 — 단지 경로를 기술한 것뿐입니다.

File 객체를 어떻게 만들까?

import java.io.File;

public class FileDemo {
    public static void main(String[] args) {
        File file = new File("example.txt"); // 상대 경로
        File folder = new File("mydir");     // 디렉터리

        System.out.println("절대 경로: " + file.getAbsolutePath());
        System.out.println("파일이 존재합니까? " + file.exists());
        System.out.println("파일인가요? " + file.isFile());
        System.out.println("디렉터리인가요? " + folder.isDirectory());
    }
}

기억해야 할 점:
File 객체를 만든다고 해서 디스크에 파일이 생성되는 것은 아닙니다. 그저 "바로가기"일 뿐입니다. 실제 파일을 만들려면 명시적으로 생성해야 합니다(예: 데이터를 기록하거나 file.createNewFile() 호출).

File 클래스의 주요 메서드

  • exists() — 파일/디렉터리가 존재하는지 확인.
  • isFile() — 파일인가? (폴더가 아님)
  • isDirectory() — 디렉터리인가?
  • getAbsolutePath() — 절대 경로 가져오기.
  • length() — 파일 크기(바이트).
  • getName() — 파일 또는 폴더 이름.
  • delete() — 파일/디렉터리 삭제(비어 있어야 함).

예제: 파일 정보 출력

File file = new File("example.txt");
System.out.println("이름: " + file.getName());
System.out.println("경로: " + file.getAbsolutePath());
System.out.println("크기: " + file.length() + " 바이트");
System.out.println("존재하나요? " + file.exists());

2. 클래스 Path: 파일에 대한 현대적 관점

Path는 새로운 파일 API(NIO.2, Java 7부터)의 일부입니다. 파일/디렉터리로의 경로를 추상화하며, 경로는 로컬 디스크뿐 아니라 ZIP 아카이브 내부나 원격 리소스(해당 프로바이더가 있을 때)일 수도 있습니다.

File이 종이 지도라면, Path는 GPS 내비게이터입니다.

Path 객체 생성 방법

import java.nio.file.Path;
import java.nio.file.Paths;

public class PathDemo {
    public static void main(String[] args) {
        Path path1 = Paths.get("example.txt"); // 상대 경로
        Path path2 = Paths.get("folder", "file.txt"); // 경로 조각 결합

        System.out.println("경로 1: " + path1.toAbsolutePath());
        System.out.println("경로 2: " + path2.toAbsolutePath());
    }
}

장점: 구분자에 신경 쓸 필요가 없습니다. Paths.get이 OS에 맞는 형식을 선택합니다.

FilePath 간 변환

  • FilePath: file.toPath()
  • PathFile: path.toFile()
File file = new File("test.txt");
Path path = file.toPath();

Path anotherPath = Paths.get("data.txt");
File anotherFile = anotherPath.toFile();

경로 작업: resolve, relativize, normalize

경로 결합(resolve)

Path dir = Paths.get("myfolder");
Path file = dir.resolve("notes.txt"); // myfolder/notes.txt
System.out.println(file); // myfolder/notes.txt

상대 경로(relativize)

Path pathA = Paths.get("folderA/file1.txt");
Path pathB = Paths.get("folderA/subfolder/file2.txt");
Path relative = pathA.relativize(pathB);
System.out.println(relative); // ../subfolder/file2.txt

경로 정규화(normalize)

Path messy = Paths.get("folder/../folder/file.txt");
Path clean = messy.normalize();
System.out.println(clean); // folder/file.txt

예제: 파일 경로 구축

Path home = Paths.get(System.getProperty("user.home"));
Path docs = home.resolve("Documents");
Path myFile = docs.resolve("myfile.txt");
System.out.println("파일 경로: " + myFile.toAbsolutePath());

3. 클래스 Files: 만능 도구

Files 클래스는 java.nio.file 패키지에 있으며, Path 기반으로 파일과 디렉터리를 다루는 정적 메서드 유틸리티 모음입니다. 존재 여부 확인, 생성/삭제, 읽기/쓰기, 복사/이동, 속성 조회, 디렉터리 트리 순회 등 거의 모든 것을 처리합니다.

Files 클래스의 주요 메서드

  • Files.exists(path) — 파일/디렉터리가 존재하는지 확인.
  • Files.isDirectory(path) — 디렉터리인지 확인.
  • Files.size(path) — 파일 크기.
  • Files.createFile(path) — 파일 생성.
  • Files.createDirectory(path) — 디렉터리 생성.
  • Files.delete(path) — 파일/디렉터리 삭제.
  • Files.copy(src, dest) — 파일 복사.
  • Files.move(src, dest) — 이동/이름 변경.
  • Files.getLastModifiedTime(path) — 마지막 수정 시각.
  • Files.readAllBytes(path) — 파일 전체를 바이트 배열로 읽기.
  • Files.readAllLines(path) — 텍스트 파일의 모든 줄 읽기.
  • Files.write(path, bytes) — 파일에 바이트 쓰기.

예제: 파일 검사

import java.nio.file.*;

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

        System.out.println("파일이 존재합니까? " + Files.exists(path));
        System.out.println("디렉터리인가요? " + Files.isDirectory(path));

        if (Files.exists(path)) {
            try {
                System.out.println("파일 크기: " + Files.size(path) + " 바이트");
            } catch (Exception e) {
                System.out.println("크기 가져오는 중 오류: " + e.getMessage());
            }
        }
    }
}

4. 실습: 객체 생성, 속성 출력

파일과 디렉터리용 객체 생성

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;

public class CompareDemo {
    public static void main(String[] args) {
        // 기존 방식
        File oldFile = new File("test.txt");
        File oldDir = new File("mydir");

        // 새로운 방식
        Path newFile = Paths.get("test.txt");
        Path newDir = Paths.get("mydir");

        System.out.println("=== File API ===");
        System.out.println("파일: " + oldFile.getAbsolutePath());
        System.out.println("존재하나요? " + oldFile.exists());
        System.out.println("파일인가요? " + oldFile.isFile());
        System.out.println("디렉터리인가요? " + oldDir.isDirectory());

        System.out.println("\n=== Path API ===");
        System.out.println("파일: " + newFile.toAbsolutePath());
        System.out.println("존재하나요? " + java.nio.file.Files.exists(newFile));
        System.out.println("파일인가요? " + java.nio.file.Files.isRegularFile(newFile));
        System.out.println("디렉터리인가요? " + java.nio.file.Files.isDirectory(newDir));
    }
}

파일 속성 출력

import java.nio.file.*;

public class FileProperties {
    public static void main(String[] args) {
        Path path = Paths.get("test.txt");

        System.out.println("절대 경로: " + path.toAbsolutePath());
        System.out.println("파일 이름: " + path.getFileName());
        System.out.println("부모 폴더: " + path.getParent());

        if (Files.exists(path)) {
            try {
                System.out.println("크기: " + Files.size(path) + " 바이트");
                System.out.println("마지막 수정: " + Files.getLastModifiedTime(path));
            } catch (Exception e) {
                System.out.println("정보 가져오는 중 오류: " + e.getMessage());
            }
        } else {
            System.out.println("파일을 찾을 수 없습니다.");
        }
    }
}

5. 비교: File vs Path/Files

기능 File (java.io) Path + Files (java.nio.file)
경로 표현 로컬 디스크만 로컬 디스크, ZIP, 네트워크 리소스
경로 결합 슬래시로 수동 연결 resolve로 쉽게
존재 여부 확인 exists() Files.exists(path)
내용 읽기/쓰기 없음 예 (Files.readAll..., Files.write)
속성 가져오기 기본(length(), lastModified()) 확장 속성과 뷰
호환성 모든 Java 버전과 호환 Java 7 이상
심링크 처리 제한적 완전 지원

요약: 언제 무엇을 사용할까?

  • 새 프로젝트에는 PathFiles를 사용하세요.
  • 레거시 코드 유지보수에는 가끔 File로 작업해야 할 때가 있습니다.

6. 유용한 팁

상대 경로와 절대 경로

상대 경로는 현재 작업 디렉터리를 기준으로 한 경로이고, 절대 경로는 파일 시스템의 루트부터 시작하는 전체 경로입니다.

Path relative = Paths.get("data", "file.txt");
Path absolute = relative.toAbsolutePath();
System.out.println("절대 경로: " + absolute);

크로스 플랫폼

PathFiles는 OS의 특성(구분자, 인코딩 등)을 고려합니다. "C:\\folder\\file.txt" 같은 경로를 직접 문자열로 작성하지 말고 Paths.getresolve를 사용하세요.

FilePath 간 변환

File 기반의 기존 코드가 있다면 새 API로 쉽게 전환할 수 있습니다:

File legacy = new File("legacy.txt");
Path modern = legacy.toPath();
if (Files.exists(modern)) {
    // 이제 NIO.2의 모든 기능을 사용할 수 있습니다
}

파일 존재 여부 확인

Path path = Paths.get("notes.txt");
if (Files.exists(path)) {
    System.out.println("파일을 찾았습니다!");
} else {
    System.out.println("파일이 존재하지 않습니다.");
}

7. 미니 실습: 파일과 디렉터리 생성 및 확인

import java.nio.file.*;

public class MiniPractice {
    public static void main(String[] args) throws Exception {
        Path dir = Paths.get("demo_dir");
        Path file = dir.resolve("hello.txt");

        // 디렉터리가 없으면 생성
        if (!Files.exists(dir)) {
            Files.createDirectory(dir);
            System.out.println("디렉터리 생성됨: " + dir.toAbsolutePath());
        }

        // 파일이 없으면 생성
        if (!Files.exists(file)) {
            Files.createFile(file);
            System.out.println("파일 생성됨: " + file.toAbsolutePath());
        }

        // 속성 출력
        System.out.println("파일이 존재합니까? " + Files.exists(file));
        System.out.println("파일인가요? " + Files.isRegularFile(file));
        System.out.println("크기: " + Files.size(file) + " 바이트");

        // 파일과 디렉터리 삭제(선택)
        Files.delete(file);
        Files.delete(dir);
        System.out.println("파일과 디렉터리가 삭제되었습니다.");
    }
}

8. File/Path/Files 작업 시 자주 발생하는 실수

실수 1: File과 Path를 혼동함. 많은 초보자가 Files 메서드를 File 객체에 쓰려고 합니다. 기억하세요: Files.*Path와 함께 동작합니다. File이 있다면 먼저 file.toPath()를 호출하세요.

실수 2: File 또는 Path 객체를 만들면 파일이 생성된다고 생각함. 경로 객체는 바로가기에 불과하며 실제 파일이 아닙니다. 파일 생성에는 Files.createFile(path) 또는 데이터 기록을 사용하세요.

실수 3: 문자열로 경로를 수동 조합. "folder/file.txt" 또는 "folder\\file.txt"처럼 작성하지 마세요. Paths.get(...)과 resolve(...)를 사용하세요. 더 안전하고 크로스 플랫폼에 적합합니다.

실수 4: 예외를 무시함. 파일 작업은 IOException 등 예외를 던질 수 있습니다. try-catch로 처리하거나 상위로 던지기(throws)를 사용하세요.

실수 5: File.exists()로 확인하고는 Path로 작업함. 한 가지 스타일을 유지하세요. Path로 시작했다면 Files.exists(path) 및 다른 Files 메서드를 사용하세요.

1
과제
JAVA 25 SELF, 레벨 35, 레슨 1
잠금
보물은 어디에? 게임 에셋 폴더 확인 🎮
보물은 어디에? 게임 에셋 폴더 확인 🎮
1
과제
JAVA 25 SELF, 레벨 35, 레슨 1
잠금
프로젝트 빌드: "메인" 파일의 전체 경로 🏗️
프로젝트 빌드: "메인" 파일의 전체 경로 🏗️
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION