2013-07-10 53 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:如果給定路徑指向一個目錄而不是常規文件,則此函數返回非零值。如果你希望它只在路徑引用常規文件時返回非零值,那麼你需要檢查'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行更改爲

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

正如Adam Rosenfield指出的那樣。在這種情況下,您可能需要將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

使用'strcat()'初始化'fullpath'是錯誤的。在第一次調用strcat()之前,'fullpath'完全沒有初始化,所以行爲是未定義的。當用一個路徑初始化fullpath時,使用'strcpy()'而不是'strcl()'(或'strncat()')來將'filename'追加到' 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()是unistd.h庫的一部分,即POSIX標準。如果你需要在其他系統下使用它,你可能需要包含不同的庫。

+0

我認爲這個問題更多的是關於如何檢查不同的路徑(如何組成路徑)。 –

+0

是的,你說得對。也許我可以發表評論,但時間太長了。 – none

相關問題