CodeGym /행동 /JAVA 25 SELF /파일 속성 가져오기 및 변경

파일 속성 가져오기 및 변경

JAVA 25 SELF
레벨 39, 레슨 4
사용 가능

1. 기본 속성 읽기: BasicFileAttributes

파일이나 폴더를 이야기할 때 이름이나 크기만을 의미하지 않습니다. 각 파일에는 “여권”과도 같은 속성 집합이 있으며, 여기에 다음이 포함됩니다:

  • 생성 시간
  • 마지막 수정 시간
  • 마지막 접근 시간
  • 크기
  • 접근 권한 (누가 읽기, 쓰기, 실행할 수 있는지)
  • 소유자 정보 (Unix)
  • “숨김”, “읽기 전용” 등의 플래그

Java에서는 이들 속성을 다루기 위한 편리하고 강력한 API가 패키지 java.nio.file.attribute에 있습니다. 플랫폼 의존 코드를 작성할 필요가 없습니다. 필요한 것은 표준 라이브러리에 모두 있습니다.

먼저 필요한 클래스를 import합니다:

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

기본 파일 속성은 어떻게 가져올까요?

Files.readAttributes 메서드를 사용합니다:

Path path = Paths.get("example.txt");
try {
    BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);

    System.out.println("생성됨: " + attrs.creationTime());
    System.out.println("수정됨: " + attrs.lastModifiedTime());
    System.out.println("마지막 접근: " + attrs.lastAccessTime());
    System.out.println("크기: " + attrs.size());
    System.out.println("디렉터리인가요? " + attrs.isDirectory());
    System.out.println("일반 파일인가요? " + attrs.isRegularFile());
    System.out.println("심볼릭 링크인가요? " + attrs.isSymbolicLink());
} catch (IOException e) {
    System.out.println("속성 읽기 중 오류: " + e.getMessage());
}

집을 검사하러 온 검사관을 상상해 보세요. 문이 있는지(파일이 존재하는지)만 보는 게 아니라, “집은 언제 지었나요? 마지막으로 수리는 언제 했나요? 집주인은 누구인가요?”라고 묻습니다.

BasicFileAttributes 속성 요약

속성 반환 내용
creationTime()
파일/폴더의 생성 날짜와 시간
lastModifiedTime()
마지막 수정 날짜와 시간
lastAccessTime()
마지막 접근 날짜와 시간
size()
파일 크기(바이트)
isDirectory()
디렉터리인가?
isRegularFile()
일반 파일인가?
isSymbolicLink()
심볼릭 링크인가?

2. 확장 속성: POSIX와 DOS

POSIX 속성(Linux, macOS 및 기타 Unix 계열 OS)

Unix 시스템에서는 접근 권한, 소유자, 그룹과 같은 확장 정보를 얻을 수 있습니다.

try {
    PosixFileAttributes posixAttrs = Files.readAttributes(path, PosixFileAttributes.class);
    System.out.println("소유자: " + posixAttrs.owner().getName());
    System.out.println("그룹: " + posixAttrs.group().getName());
    System.out.println("권한: " + PosixFilePermissions.toString(posixAttrs.permissions()));
} catch (UnsupportedOperationException e) {
    System.out.println("이 OS에서는 POSIX 속성을 지원하지 않습니다.");
} catch (IOException e) {
    System.out.println("POSIX 속성 읽기 중 오류: " + e.getMessage());
}

참고: Windows에서는 이 코드는 UnsupportedOperationException을 던집니다. 정상 동작입니다.

DOS 속성(Windows)

Windows에서는 “읽기 전용”, “숨김”, “아카이브”, “시스템” 플래그를 다룰 수 있습니다:

try {
    DosFileAttributes dosAttrs = Files.readAttributes(path, DosFileAttributes.class);
    System.out.println("숨김: " + dosAttrs.isHidden());
    System.out.println("읽기 전용: " + dosAttrs.isReadOnly());
    System.out.println("시스템: " + dosAttrs.isSystem());
    System.out.println("아카이브: " + dosAttrs.isArchive());
} catch (UnsupportedOperationException e) {
    System.out.println("이 OS에서는 DOS 속성을 지원하지 않습니다.");
} catch (IOException e) {
    System.out.println("DOS 속성 읽기 중 오류: " + e.getMessage());
}

3. 파일 속성 변경

남의 여권을 읽는 것과 생년월일이나 성을 바꾸는 것은 전혀 다른 일입니다! Java에서는 (적절한 권한이 있다면) 파일의 속성을 변경할 수도 있습니다.

마지막 수정 시간 변경

import java.nio.file.attribute.FileTime;

Path file = Paths.get("example.txt");
try {
    FileTime newTime = FileTime.fromMillis(System.currentTimeMillis() - 24 * 60 * 60 * 1000); // 1일 전
    Files.setLastModifiedTime(file, newTime);
    System.out.println("마지막 수정 시간이 변경되었습니다!");
} catch (IOException e) {
    System.out.println("시간 변경 중 오류: " + e.getMessage());
}

접근 권한 변경(POSIX)

Unix 시스템에서만 가능합니다! 예를 들어, 모든 사용자가 실행할 수 있도록 설정하기:

try {
    Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-xr-x");
    Files.setPosixFilePermissions(file, perms);
    System.out.println("권한이 변경되었습니다!");
} catch (UnsupportedOperationException e) {
    System.out.println("이 OS에서는 POSIX 권한을 지원하지 않습니다.");
} catch (IOException e) {
    System.out.println("권한 변경 중 오류: " + e.getMessage());
}

문자열 "rwxr-xr-x" 설명:

  • r — read(읽기)
  • w — write(쓰기)
  • x — execute(실행)
  • 첫 세 글자는 소유자, 다음은 그룹, 마지막은 그 외 사용자입니다.

숨김/읽기 전용 상태 변경(DOS 속성, Windows)

파일을 숨김으로 설정:

try {
    Files.setAttribute(file, "dos:hidden", true);
    System.out.println("파일이 숨김으로 설정되었습니다(Windows)!");
} catch (UnsupportedOperationException e) {
    System.out.println("이 OS에서는 DOS 속성을 지원하지 않습니다.");
} catch (IOException e) {
    System.out.println("속성 변경 중 오류: " + e.getMessage());
}

파일을 “읽기 전용”으로 설정:

try {
    Files.setAttribute(file, "dos:readonly", true);
    System.out.println("파일이 이제 읽기 전용입니다(Windows)!");
} catch (UnsupportedOperationException e) {
    System.out.println("이 OS에서는 DOS 속성을 지원하지 않습니다.");
} catch (IOException e) {
    System.out.println("속성 변경 중 오류: " + e.getMessage());
}

4. 접근 권한 확인

가끔은 파일을 읽기, 쓰기, 실행할 수 있는지 빠르게 확인하는 것이 중요합니다:

Path file = Paths.get("example.txt");
System.out.println("읽기 가능: " + Files.isReadable(file));
System.out.println("쓰기 가능: " + Files.isWritable(file));
System.out.println("실행 가능: " + Files.isExecutable(file));

모든 플랫폼에서 동일하게 동작하지만, 실제 동작은 OS와 보안 설정에 따라 달라질 수 있습니다.

5. 실습: 파일 상세 정보 출력

파일 경로를 받아 가능한 한 많은 정보를 보여 주고 몇 가지 속성 변경도 시도하는 작은 프로그램을 작성해 보겠습니다.

import java.nio.file.*;
import java.nio.file.attribute.*;
import java.util.Set;
import java.io.IOException;

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

        if (!Files.exists(path)) {
            System.out.println("파일을 찾을 수 없습니다!");
            return;
        }

        // 기본 속성
        BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
        System.out.println("이름: " + path.getFileName());
        System.out.println("경로: " + path.toAbsolutePath());
        System.out.println("크기: " + attrs.size() + " 바이트");
        System.out.println("생성됨: " + attrs.creationTime());
        System.out.println("수정됨: " + attrs.lastModifiedTime());
        System.out.println("마지막 접근: " + attrs.lastAccessTime());
        System.out.println("디렉터리인가요? " + attrs.isDirectory());
        System.out.println("일반 파일인가요? " + attrs.isRegularFile());

        // 접근 권한 확인
        System.out.println("읽기 가능: " + Files.isReadable(path));
        System.out.println("쓰기 가능: " + Files.isWritable(path));
        System.out.println("실행 가능: " + Files.isExecutable(path));

        // 수정 시간 변경 시도
        FileTime now = FileTime.fromMillis(System.currentTimeMillis());
        Files.setLastModifiedTime(path, now);
        System.out.println("마지막 수정 시간이 업데이트되었습니다!");

        // 파일을 숨김으로 설정 시도(지원되는 경우)
        try {
            Files.setAttribute(path, "dos:hidden", true);
            System.out.println("파일이 숨김으로 설정되었습니다(OS가 지원하는 경우).");
        } catch (UnsupportedOperationException e) {
            System.out.println("이 OS에서는 숨김 파일을 지원하지 않습니다.");
        }

        // POSIX 권한 출력 시도(지원되는 경우)
        try {
            PosixFileAttributes posixAttrs = Files.readAttributes(path, PosixFileAttributes.class);
            System.out.println("소유자: " + posixAttrs.owner().getName());
            System.out.println("권한: " + PosixFilePermissions.toString(posixAttrs.permissions()));
        } catch (UnsupportedOperationException e) {
            System.out.println("이 OS에서는 POSIX 속성을 지원하지 않습니다.");
        }
    }
}

6. 유용한 팁

크로스플랫폼 차이와 팁

  • 모든 OS에서 모든 속성을 사용할 수 있는 것은 아닙니다! Windows에는 POSIX 권한이 없고, Linux에는 DOS 속성이 없습니다.
  • 항상 try-catch를 사용하세요! 메서드는 UnsupportedOperationException이나 IOException을 던질 수 있습니다.
  • 접근 권한이 항상 “rwx”만은 아닙니다! Windows의 권한 모델은 다르며, “읽기 전용”은 OS의 보안 정책으로 설정될 수 있습니다.
  • 숨김 파일의 개념은 상대적입니다. Unix에서는 이름이 점으로 시작하면(.hidden) 숨김이고, Windows에서는 속성 dos:hidden이 설정되면 숨김입니다.

표: 어떤 속성이 어디에서 가능한가

속성 Windows (dos:*) Linux/macOS (posix:*)
생성 시간 + +
마지막 수정 시간 + +
마지막 접근 시간 + +
숨김 파일 + 점으로 시작하는 이름만
읽기 전용 + +
접근 권한 (rwx) - +
소유자, 그룹 - +
아카이브, 시스템 + -

7. 파일 속성 작업 시 흔한 실수

오류 №1: Windows에서 POSIX 속성을 읽거나 변경하려는 시도. Windows에서는 UnsupportedOperationException이 발생합니다. 크로스플랫폼 코드를 작성할 때는 항상 이 예외를 처리하세요.

오류 №2: 다른 프로세스가 열고 있는 파일의 수정 시간을 변경하려는 경우. 일부 시스템에서는 파일이 잠겨 있어 작업이 실패할 수 있습니다.

오류 №3: “파일 숨기기”가 모든 OS에서 동일하게 동작한다고 기대하는 경우. Unix에서는 이름이 점으로 시작하는(.gitignore) 파일이 숨김이고, Windows에서는 속성 dos:hidden이 설정되어야 합니다. 이 접근 방식을 혼동하지 마세요.

오류 №4: 작업 전에 파일 존재 여부를 확인하지 않는 경우. 파일이 없으면 속성을 가져오거나 변경하려 할 때 NoSuchFileException이 발생합니다.

오류 №5: 권한 검사를 하지 않는 경우. 사용자에게 속성 변경 권한이 없으면 작업이 실패합니다. 변경 전에 Files.isWritable(path)를 확인하세요.

1
과제
JAVA 25 SELF, 레벨 39, 레슨 4
잠금
보안 전문가: 접근 권한 감사
보안 전문가: 접근 권한 감사
1
과제
JAVA 25 SELF, 레벨 39, 레슨 4
잠금
아카이브 관리자: 타임스탬프 갱신
아카이브 관리자: 타임스탬프 갱신
1
설문조사/퀴즈
파일 시스템 작업, 레벨 39, 레슨 4
사용 불가능
파일 시스템 작업
파일 시스템 작업
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION