我有函數來檢查文件存在:如何檢查文件是否存在於特定的目錄中?
int file_exists(char *filename)
{
struct stat buffer;
int i = stat(filename, &buffer);
if (i == 0) {
return 1;
}
return 0;
}
,它工作正常完整路徑,但我要檢查,如果文件中的用戶主目錄中,如果沒有 - 在/ etc目錄中。怎麼做?
我有函數來檢查文件存在:如何檢查文件是否存在於特定的目錄中?
int file_exists(char *filename)
{
struct stat buffer;
int i = stat(filename, &buffer);
if (i == 0) {
return 1;
}
return 0;
}
,它工作正常完整路徑,但我要檢查,如果文件中的用戶主目錄中,如果沒有 - 在/ etc目錄中。怎麼做?
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
)。
只有以「文件名」作爲輸入,然後使用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;
}
注:代碼沒有進行測試,這只是給你一個提示。在實施時做適當的理智檢查。希望這會給你一些想法!
好吧,我已經用溢出檢查文件名更新了我的答案,現在它是安全的。而且由於我們事先知道這個大小,所以沒有特別需要使用strncat()。謝謝! –
使用'strcat()'初始化'fullpath'是錯誤的。在第一次調用strcat()之前,'fullpath'完全沒有初始化,所以行爲是未定義的。當用一個路徑初始化fullpath時,使用'strcpy()'而不是'strcl()'(或'strncat()')來將'filename'追加到' fullpath'。 –
好吧,我已經提出了使用fullpath 0然後使用strcat()的建議,但是,我完全不同意你說strcat()在這裏是不安全的。我們*事先知道*大小,我們知道我們在做什麼。因爲,每個人都想要strncat(),所以我做了改變。 –
始終提供您的路徑的完整地址,或當前目錄中的./。
此外,根據此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標準。如果你需要在其他系統下使用它,你可能需要包含不同的庫。
我認爲這個問題更多的是關於如何檢查不同的路徑(如何組成路徑)。 –
是的,你說得對。也許我可以發表評論,但時間太長了。 – none
函數體的最後4行等價於'return!i;'。 –
@Nips:如果給定路徑指向一個目錄而不是常規文件,則此函數返回非零值。如果你希望它只在路徑引用常規文件時返回非零值,那麼你需要檢查'struct stat'的'st_mode'成員。例如,'return(stat(filename,&buffer)== 0 && S_ISREG(buffer.st_mode));' –