HOWTO · Java

Java에서 파일의 파일 확장자를 얻는 방법

이 게시물은 Java에서 파일의 파일 확장자를 얻는 방법을 소개합니다.

이 페이지의 내용

파일 확장자는 student-records.pdf의 pdf처럼 이름에서 마지막 점 뒤에 오는 접미사입니다. Java에는 File이나 String에 확장자만 가져오는 전용 메서드가 없으므로, Apache Commons IO의 FilenameUtils 같은 유틸리티를 호출하거나 String 메서드로 마지막 점의 위치를 직접 찾아야 합니다. 아래에서는 두 가지 방법과 전체 경로에서도 올바르게 동작하게 하는 규칙을 함께 보여줍니다.

Apache Commons IO로 파일 확장자 가져오기

FilenameUtils.getExtension()는 파일 이름이나 경로에서 마지막 점 뒤의 텍스트를 반환합니다. /와 \ 두 경로 구분자를 모두 인식하므로 디렉터리 이름 안의 점이 확장자로 잘못 처리되지 않으며, 사용할 수 있는 확장자가 없는 이름에는 ""를 반환합니다.

이 클래스는 JDK에 포함되어 있지 않으므로 Maven이나 Gradle을 통해 프로젝트에 commons-io 의존성을 추가하거나 JAR를 클래스패스에 두어야 합니다. 의존성을 추가한 후에는 org.apache.commons.io.FilenameUtils를 임포트하고 String extension = FilenameUtils.getExtension(fileName);처럼 호출합니다. fileName이 student-records.pdf이면 pdf를 반환합니다.

이 API 호출은 컴파일 시 외부 라이브러리가 필요하므로 인라인으로만 보여줍니다. 아래의 실행 가능한 예제는 JDK만 사용합니다.

Java 문자열 메서드로 확장자 추출하기

일반 파일 이름에는 라이브러리가 필요하지 않습니다. lastIndexOf('.')가 마지막 점을 찾고 substring()이 그 뒤의 모든 내용을 가져옵니다.

다음 예제를 실행해 보세요.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

public class SimpleTesting {
  public static void main(String[] args) {
    String fileName = "student-records.pdf";
    int dot = fileName.lastIndexOf('.');
    String extension = dot > 0 ? fileName.substring(dot + 1) : "";
    System.out.println("File extension is : " + extension);
  }
}

출력은 다음과 같습니다. 코드 블록 안의 라벨은 원문인 영어로 유지됩니다.

File extension is : pdf

dot > 0 검사는 보고할 확장자가 없는 두 가지 경우를 처리합니다. readme에서는 lastIndexOf가 -1을 반환하므로 ""가 생성되고, .env처럼 이름이 점으로 시작하는 경우에는 그 점을 확장자 구분자가 아니라 이름 표시로 간주합니다. 다만 이 간단한 형태로는 점이 이름의 디렉터리 부분에 있는지 알 수 없습니다. 이 경우에는 다음에 나오는 경로 인식 버전이 필요합니다.

경로와 예외적인 경우 처리하기

전체 경로에서는 확장자를 구분하는 점이 마지막 경로 구분자 뒤에 있어야 합니다. 아래 헬퍼는 /와 \를 모두 검사하므로 data.d처럼 점이 포함된 폴더가 결과로 새어 나오지 않습니다. 점이 없는 이름, 점으로 시작하는 이름, 점으로 끝나는 이름에는 ""를 반환합니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

public class SimpleTesting {

  static String fileExtension(String path) {
    if (path == null) {
      return "";
    }
    int dot = path.lastIndexOf('.');
    int sep = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
    if (dot <= sep + 1 || dot == path.length() - 1) {
      return "";
    }
    return path.substring(dot + 1);
  }

  public static void main(String[] args) {
    String[] names = {
        "folder/s.gr/fg/student-records.pdf",
        "C:\\data.d\\reports\\summary.txt",
        "folder.d/README",
        "folder/.hidden",
        "archive.tar."
    };
    for (String name : names) {
      System.out.println(name + " -> '" + fileExtension(name) + "'");
    }
  }
}

출력은 다음과 같습니다. 코드 블록 안의 라벨은 원문인 영어로 유지됩니다.

folder/s.gr/fg/student-records.pdf -> 'pdf'
C:\data.d\reports\summary.txt -> 'txt'
folder.d/README -> ''
folder/.hidden -> ''
archive.tar. -> ''

점의 위치는 sep가 아니라 sep + 1과 비교되므로 마지막 이름 세그먼트의 첫 번째 위치에 있는 점도 ""를 반환합니다. 즉, 이 헬퍼는 .hidden을 확장자가 없는 숨김 파일로 처리합니다. FilenameUtils.getExtension()도 같은 구분자 검사를 수행하지만 이 경우에는 다른 규칙을 적용해 .hidden에서 hidden을 반환합니다. 두 방법 모두 folder.d/README와 archive.tar.에서는 ""를 반환한다는 점에는 동의합니다. 호출하는 쪽이 기대하는 규칙에 맞는 방식을 선택하세요.

적합한 접근 방식 선택하기

Apache Commons IO가 이미 클래스패스에 있거나 한 번의 호출로 잘 검증된 결과를 얻고 싶다면 FilenameUtils.getExtension()를 사용하세요. 이 메서드는 두 가지 경로 구분자와 점이 포함된 디렉터리를 추가 설정 없이 처리합니다. 의존성을 전혀 두지 않으려 하거나 라이브러리를 추가할 수 없는 경우, 또는 위에 나온 점으로 시작하는 이름 처리처럼 사용자 지정 규칙이 필요한 경우에는 String 버전을 사용하세요. 단, 그 경우에는 구분자와 끝의 점을 직접 검사해야 합니다.

이미 파일 I/O를 수행하는 대부분의 프로젝트에서는 FilenameUtils.getExtension()가 더 간단하고 안전한 선택입니다. 작은 유틸리티나 제한된 클래스패스라면 경로 인식 헬퍼가 몇 줄만으로 같은 범위를 처리할 수 있습니다.