2013-07-10 2 views
1

나는 기존 파일 확인하는 기능이 있습니다특정 디렉토리에 파일이 있는지 확인하는 방법은 무엇입니까?

int file_exists(char *filename) 
{ 
    struct stat buffer; 
    int i = stat(filename, &buffer); 
    if (i == 0) { 
     return 1; 
    } 
    return 0; 
} 

을하며 전체 경로로 잘 작동하지만 나는 파일이 사용자 홈 디렉토리에 존재하지 않을 경우 있는지 확인하려면 -/etc 디렉토리에. 그것을하는 방법?

+3

함수 본문의 마지막 4 행은'return! i;'와 같습니다. –

+1

@Nips :이 함수는 주어진 경로가 일반 파일 대신 디렉토리를 참조하는 경우 0이 아닌 값을 반환합니다. 경로가 정규 파일을 참조하는 경우에만 0이 아닌 값을 반환하려면'struct stat'의'st_mode' 멤버를 검사해야합니다. 예 :'return (stat (filename, & buffer) == 0 && S_ISREG (buffer.st_mode)); ' –

답변

2
int 
file_exists(const char *basename) 
{ 
    static const char *dirs[] = { "/etc", "/home/username" }; 
    char buf[MAX_PATH_LENGTH + 1]; 
    size_t i; 
    struct stat dummy; 

    for (i = 0; i < sizeof dirs/sizeof dirs[0]; ++i) { 
     (void)snprintf(buf, sizeof buf, "%s/%s", dirs[i], basename); 
     if (!stat(buf, &dummy)) return 1; 
    } 

    return 0; 
} 

경로와 파일 이름이 MAX_PATH_LENGTH자를 초과하는 경우 오류가 발생합니다 (즉, 잘못된 파일을 검색). 그것을 얻으려면 snprintf의 반환 값을 확인할 수 있습니다.

디렉토리/소켓/디렉토리를 찾으려면 ..., 당신은 아담 로젠에 의해 지적으로

if (!stat(buf, &dummy) && S_ISREG(dummy.st_mode)) return 1; 

if 라인을 변경할 수 있습니다. 이 경우 dummy의 이름을 더 적절하게 (어쩌면 sb) 바꿉니다.

0

errno 값을 사용하면 파일이없는 경우 ENOENT이됩니다. 당신의 문제에 대한

#include <errno.h> 
int file_exists(char *filename) 
{ 
    struct stat buffer; 
    int i = stat(filename, &buffer); 
    if (i == 0) { 
     return 1; 
    } 
    if (errno == ENOENT) 
     printf("%s : file not found\n", buffer); 
    return 0; 
} 

: 당신이 당신의 파일 이름으로 디렉토리를 연결할 필요하지 않으려면 chdir를 사용합니다. 입력으로

0

만 가지고 "파일 이름", 다음의 전체 경로 이름을 만들 strcat와를 사용 - 뭔가를 아래와 같이 :

int file_exists(char *filename) 
{ 
    struct stat buffer; 
    char fullpath[50], *path; 
    path = "/home/Nips/" 
    if ((strlen(path) + strlen(filename)) >= 50) { 
     printf("filename too long!\n"); 
     return 0; 
    } 
    strcpy(fullpath, path); 
    strcat(fullpath, filename); 
    if (stat(fullpath, &buffer) == 0) { 
     return 1; 
    } 
    if (errno == ENOENT) { 
     path = "/etc/"; 
     strcpy(fullpath, path); 
     strcat(fullpath, filename); 
     if (stat(fullpath, &buffer) == 0) { 
      return 1; 
     } 
     if (errno == ENOENT) { 
      printf("File not found!\n"); 
      return 0; 
     } 
    } 
    printf("Error finding File!\n"); 
    return 0; 
} 

참고 : 코드는 테스트되지 않으며, 이것은 단지 당신에게 힌트를 줄 수 있습니다. 당신이 구현하는 동안 적절한 정신 테스트를해라. 희망이 당신에게 어떤 생각을 줄 것이다!

+0

그래, 파일 이름에 대한 오버플로 검사로 답변을 업데이트 했으니 이제는 안전하다. 그리고 미리 크기를 알고 있으므로 strncat()을 사용하는 데 특별히 필요한 것은 없습니다. 감사! –

+2

'fullpath'를 초기화하기 위해'strcat()'를 사용하는 것은 잘못되었습니다. 'fullpath'는'strcat()'이 처음 호출되기 전에 전혀 초기화되지 않으므로, 동작은 정의되지 않습니다. 'fullpath'를 경로로 초기화 할 때'strcpy()'대신에'strcpy()'를 사용하고,'strcat()'(또는'strncat()') fullpath'. –

+0

좋아, 내가 당신에게 fullpath 0을 제안하고 strcat()를 사용하여,하지만, 난 전혀 당신이 여기에 strcat() 안전하지 않습니다 동의 해요. 우리는 * 크기를 미리 알고 있습니다. 우리는 우리가하는 일을 알고 있습니다. 모두가 strncat()을 원하므로 변경을했습니다. –

0

항상 현재 주소 나 전체 경로에 전체 주소를 제공하십시오.

또한 similar question에 따르면 액세스 (경로 이름, 모드) 함수는 필요한 것을 수행합니다. 대신 사용하십시오. 성공시 0을 반환하고 실패 할 경우 -1을 반환합니다. access()가 필요한만큼 정확하게 수행하기 때문에 다시 구현할 필요가 없습니다. 가장 일반적인 형태는 다음과 같다

참고 :

F_OK, 파일이 존재하는지 확인합니다.

R_OK, 읽기 용.

W_OK, 쓰기 용.

X_OK, 사용 권한 읽기, 쓰기 및 실행 용. 예를 들어 당신이 읽기와 쓰기 권한을 모두 확인해야하는 경우

또한, 당신은 R_OK 및 W_OK (또는 각 세 R_OK, W_OK 또는 X_OK 사이) 자세한 내용은

사이의 비트 또는를 가질 수 있습니다 터미널에 사람 액세스을 입력하거나 위 링크를 방문하십시오.

주의점 : access()는 POSIX 표준 인 unistd.h 라이브러리의 일부입니다. 다른 시스템에서 사용해야 할 경우 다른 라이브러리를 포함해야 할 수도 있습니다.

+0

다른 경로 (경로를 작성하는 방법)를 확인하는 방법에 대한 질문이 더 많습니다. –

+0

예, 당신 말이 맞아요. 어쩌면 내가 코멘트를 게시 할 수도 있지만 너무 길었습니다. – none

관련 문제