linux+筆記:linux下判斷一個文件或者目錄是否存在

工作中涉及到文件系統,有時候需要判斷文件和目錄是否存在,下面是一些前人的經驗分享。

轉自:http://blog.csdn.net/adcxf/article/details/6386901
轉自:http://www.cnblogs.com/Anker/p/3349672.html

判斷文件存在

對於判斷文件是否存在,每個人有不同的方法!我通常採用兩種方法 : open 和 access ;

這個倆個方法有相似之處,且有不同之處;下面爲大家詳細說明他們的不同之處:

open 是打開,讀寫等操作文件的一個函數,access就是一個判斷文件權限的函數。在Linux下,由於文件有不同的權限,噹噹前用戶沒有對此文件的讀權限的時候,用來判斷文件是否存在,顯然不合適。而access卻可以做到。

open 的第一個參數是文件路徑,第二個參數是打開文件選項,常用的有O_RDONLY(讀),O_WRONLY(寫),O_RDWR(讀寫),O_CREAT(創建)。 第三個參數通常在創建文件的時候才使用,給文件設定權限使用。

access的第一個參數是文件路徑,第二個參數是測試的模式。常用的有R_OK:測試讀權限,W_OK:測試寫權限,X_OK:測試執行權限,F_OK:測試文件是否存在;

access函數

  access函數按照實際用戶ID和實際組進行訪問權限測試。函數原型爲:

#include <unistd.h>
int access(const char *pathname, int mode);

mode取值:

F_OK  測試文件是否存在

R_OK  測試讀權限

W_OK  測試寫權限

X_OK  測試執行權限

正確判斷一個文件是否存在是用access函數,實現如下所示:

#include <unistd.h>

int is_file_exist(const char *file_path)
{
    if(file_path == NULL)
        return -1;

    if( access(file_path, F_OK) == 0 )
        return 0;
    return -1;
}

我做個例子,寫一個小程序來看兩者的區別。
測試測序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc , char **argv)
{
char path[50];
memset(path,0,50);
sprintf(path,"%s","./test");
int fd;

printf("access function -------------------------/n");

if((fd = access (path,F_OK)) == 0)
printf("[access] file exist!/n");    
else    
printf("[access] file not exist!!/n");

if((fd = access (path,R_OK)) == 0)
printf("[access] read file ok!/n");
else    
printf("[access] read file no!/n");

if((fd = access (path,W_OK)) == 0)
printf("[access] write file ok!/n");
else    
printf("[access] write file no!/n");

if((fd = access (path,X_OK)) == 0)
printf("[access] execute file ok!/n");
else    
printf("[access] execute file no!/n");

printf("open  function -------------------------/n");


if((fd = open (path,O_RDONLY)) == -1)
printf("[open] open no!/n");
else    
{
close(fd);
printf("[open] open ok!/n");
}

if((fd = open (path,O_WRONLY)) == -1)
printf("[open] write no!/n");
else    
{
close(fd);
printf("[open] write ok!/n");
}
if((fd = open (path,O_RDWR)) == -1)
printf("[open] rdwr no!/n");
else    
{
close(fd);
printf("[open] rdwr ok!/n");
}
}

首先我們創建一個普通文件 test , 修改文件權限爲0744,修改文件屬主爲root. 我們在普通用戶mpeg4下操作.

[mpeg4@mc2800 file1]$ sudo chown root:root test
[mpeg4@mc2800 file1]$ sudo chmod 0744 test
[mpeg4@mc2800 file1]$ ls -l
total 20
-rwxrwxrwx 1 mpeg4 mpeg4 7157 2009-09-17 09:37 file
-rwxrwxrwx 1 mpeg4 mpeg4  991 2009-09-17 09:44 file.c
-rwxrwxrwx 1 mpeg4 mpeg4   94 2009-09-17 08:56 makefile
-rwxrwxrwx 1 mpeg4 mpeg4 3808 2009-08-20 13:52 records
-rwxr--r-- 1 root  root     0 2009-09-17 10:06 test

好了,我們運行我的程序看結果:

[mpeg4@mc2800 file1]$ ./file
access function -------------------------
[access] file exist!
[access] read file ok!
[access] write file no!
[access] execute file no!
open  function -------------------------
[open] open ok!
[open] write no!
[open] rdwr no!

很明顯在用戶有讀權限的情況下,使用那個函數用來判斷文件是否存在都可以。
現在我們把文件的權限改爲0740:

sudo chmod 0740 test

再看測試結果:

[mpeg4@mc2800 file1]$ ./file
access function -------------------------
[access] file exist!
[access] read file no!
[access] write file no!
[access] execute file no!
open  function -------------------------
[open] open no!
[open] write no!
[open] rdwr no!

可以看到,文件權限改變了,就不能用open函數來判斷文件是否存在了。

我相信很多人都喜歡用open函數來判斷文件是否存在,當然大家也都知道關於權限的問題,所以會採用一些必要測措施來控制出錯。但是我建議判斷文件是否存在最好用access函數。當我們要讀取文件內容的時候可以使用open來判斷文件是否存在,就算是因爲沒有讀權限或者文件真的不存在,都無法實現讀的操作,我們的目的也就達到了。

stat系列函數

  stat函數用來返回與文件有關的結構信息。stat系列函數有三種情況,分別對應文件名稱、文件描述符和符號鏈接文件。stat結構描述了文件的屬性,主要包括文件的類型、文件大小等等。詳細stat結構如下所示:

  struct stat {
      mode_t    st_mode;    // file type & mode(permissions)
      ino_t     st_ino;     // i-node number(serial number)
      dev_t     st_dev;     // device number(filesystem)
      dev_t     st_rdev;    // device number for specials files
      nlink_t   st_nlink;   // number of links
      uid_t     st_uid;     // user ID of owner
      gid_t     st_gid;     // group ID of owner
      off_t     st_size;    // size in bytes, for regular files
      time_t    st_atime;   // time of last access
      time_t    st_mtime;   // time of last modification
      time_t    st_ctime;   // time of last file status change
      long      st_blksize; // best I/O block size
      long      st_blocks;  // number of 512-byte blocks allocated
   };

我們可以通過stat獲取文件的類型和文件大小等信息。文件類型有:普通文件、目錄文件、塊特殊文件、字符特殊文件、FIFO、套接字和符號鏈接。要想通過stat系列函數來判斷文件或者目錄是否存在,當執行stat函數,如果文件存在時,還需進一步判斷該文件是普通文件還是目錄文件。

stat系列函數錯誤返回-1,錯誤碼存在errno中,errno取值如下:

1、ENOENT 參數file_name 指定的文件不存在
2、ENOTDIR 路徑中的目錄存在但卻非真正的目錄
3、ELOOP 欲打開的文件有過多符號連接問題, 上限爲16 符號連接
4、EFAULT 參數buf 爲無效指針, 指向無法存在的內存空間
5、EACCESS 存取文件時被拒絕
6、ENOMEM 核心內存不足
7、ENAMETOOLONG 參數file_name 的路徑名稱太長

判斷目錄:oepndir函數

opendir函數用來打開文件目錄,成功返回指針,出錯返回NULL。
函數原型爲:

#include <sys/types.h>
#include <dirent.h> 
DIR *opendir(const char *name);

實現如下:

#include <sys/types.h>
#include <dirent.h>

int is_dir_exist(const char *dir_path)
{
    DIR *dirptr = NULL;

    if(dir_path== NULL)
        return -1;

    if( dirptr=opendir(dir_path) == 0 ){
        return -1;
    }
    closedir(dirptr );
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章