정말 File.Exists 호출이 필요할까요?

File.Exists 사용에 대한 주요 포인트

  • File.Exists(path) 메서드는 파일이 존재하는지를 확인하는 데 사용됩니다. 그러나 이 방법은 여러 가지 이유로 문제가 발생할 수 있습니다.

문제점

  1. 파일 상태 변화:

    • 다른 애플리케이션이 파일을 삭제할 수 있습니다 (예: 안티바이러스 프로그램).
    • 디스크가 제거되거나 언마운트될 수 있습니다.
    • 네트워크 드라이브의 연결이 끊길 수 있습니다.
    • Windows Projected File System (ProjFS) 서비스가 중지될 수 있습니다.
  2. 파일 접근 문제:

    • 파일이 존재하더라도 권한 문제로 열 수 없을 수 있습니다.
    • 파일이 읽기 전용 또는 숨김 속성일 수 있습니다.
    • 파일이 잠겨 있을 수 있습니다 (파일 공유).
    • 디스크에 오류가 발생할 수 있습니다.

권장 사항

  • 파일이나 디렉토리의 존재 여부를 확인하는 대신, 직접 작업을 수행하고 발생할 수 있는 오류를 처리하는 것이 좋습니다.

예시 코드

try
{
    using var stream = File.Open(path, FileMode.Open);
    // TODO
}
catch (FileNotFoundException)
{
    // TODO
}
catch (DirectoryNotFoundException)
{
    // TODO
}
catch (UnauthorizedAccessException)
{
    // TODO
}
catch (Exception)
{
    // TODO
}
  • 디렉토리 작업에서도 동일한 원칙이 적용됩니다:
// 디렉토리 생성
Directory.CreateDirectory(path);

// 디렉토리 삭제
try
{
    Directory.Delete(path);
}
catch (DirectoryNotFoundException)
{
    // ok
}
catch (Exception ex)
{
    // TODO
}

결론

  • File.Exists를 사용하여 파일의 존재 여부를 확인하는 것은 안전하지 않으며, 대신 직접 작업을 수행하고 예외를 처리하는 것이 더 효과적입니다.
15 Likes

이 기사의 내용을 보고 궁금해 진 것이 있어서 테스트해본 내용을 추가합니다. 저는 Directory.Exists API를 많이 사용하기 때문에 찾아본 내용입니다.

Directory.Exists API를 사용하지 않고 디렉터리를 만드는 것을 확실시하려면 Directory.CreateDirectory API가 이미 들어있는 디렉터리에 대해서 지우거나 예외를 던지는 동작이 없어야 Exists API 호출을 생략할 수 있겠다는 생각이 들어서 테스트해보니, 이미 있는 디렉터리에 대해서는 아무것도 하지 않고 지나가도록 되어있었습니다.

반면, Directory.Delete의 경우 디렉터리가 없으면 DirectoryNotFoundException 예외를 던집니다. 이런 특성을 숙지하여 기존 코드를 개선해야 할 필요가 있겠습니다.

8 Likes

오 흥미로운 내용이네요 감사합니다

2 Likes

File.Exists를 사용하더라도 조건문과 실제 파일 작업 사이 다른 프로세스나 혹은 스레드가
파일을 삭제(혹은 이동) 할 수 있으므로 예외처리를 하는것이 더 좋을것 같습니다.

2 Likes

저도 File.Exists가 대부분의 상황에서 사족이라는 인상이 강한거같습니다. 파일의 유무 자체로 어떤 기능적 분기가 있는게 아니라면, 미리 체크한다고해서 어떤 유효성을 보장하거나 코드를 간소화할수있다던가 하는 의미가 별로 없는거같아요

2 Likes

별로 크게 생각해보지 않았던 주제인데 재미있네요

3 Likes