2011-12-15 59 views
3

我是C新手,但嘗試了一些系統調用。C編程 - Stat系統調用 - 錯誤

我正在編寫遍歷目錄中所有文件並打印當前文件名和大小的程序。我可以讓程序打印文件名,但是當我執行統計系統調用時會出錯。

下面是一些代碼:

while (dptr = readdir(dirp)) { 
      if (stat(dptr->d_name, &buf) != 0) { 
       //Always does this and it does print the file name 
       printf("Error on when getting size of %s \n", dptr->d_name); 
      } else { 
       //Never gets here 
       printf("%u", buf.st_size); 
       }   
} 

我有這樣的描述結構:

struct stat buf; 
struct dirent *dptr; 
DIR *dirp; 

如果我改變:

if (stat(dptr->d_name, &buf) != 0) 

if (stat(dptr->d_name, &buf) != [EACCES]) 

它仍然進入循環,這讓我認爲它不能讀取文件名,但它將錯誤語句打印出來沒有問題。

有人能指出我正確的方向嗎?謝謝!

Аркадий

+2

是您所提供的_full_路徑的文件和文件夾的名稱? – 2011-12-15 18:45:23

+2

`stat`永遠不會返回`EACCES`。它將返回-1,然後將`errno`設置爲`EACCES`。 – 2011-12-15 18:51:50

+0

當它在當前目錄中時它工作嗎? (根據@ codaddict的回答) – 2011-12-15 19:00:05

回答

3

首先,如果遇到錯誤,stat()返回-1,而不是實際的錯誤代碼。錯誤代碼將在errno中設置。打印錯誤的簡單方法是使用perror()。

其次,dptr-> d_name只提供文件的相對文件名,而不提供完整的文件名。要獲得完整的文件名,您必須從相對文件名和目錄名稱中生成它。

下面是一個例子:

int cwdloop(void) 
{ 
    DIR   * dirp; 
    struct stat  buff; 
    struct dirent * dptr; 
    char   filename[1024]; 
    char   dirname[1024]; 

    if (!(getcwd(dirname, 1024))) 
    { 
     perror("getcwd"); 
     return(1); 
    }; 

    dirp = opendir(dirname); 
    if (!(dirp)) 
    { 
     perror("opendir()"); 
     return(1); 
    }; 

    while ((dptr = readdir(dirp))) 
    { 
     snprintf(filename, 1024, "%s/%s", dirname, dptr->d_name); 
     if (stat(filename, &buff) != 0) 
     { 
     perror("stat()"); 
     return(1); 
     } else { 
     printf("size: %u\n", (unsigned)buff.st_size); 
     }; 
    }; 

    closedir(dirp); 

    return(0); 
} 
3

這些東西是一個更容易對付,如果你知道確切的錯誤。嘗試

printf("error = %d: %s", errno, strerror(errno)); 
+1

或者只是使用`perror()`。 – kennytm 2011-12-15 18:34:50

3

這種代碼的一個常見問題是隻使用文件名作爲路徑名。 dirent結構的d_name條目不提供完整的路徑名,但提供了與您的目錄相關的路徑名。

要解決這一點,你可以

  1. 構建完整路徑名,然後調用stat之前將它傳遞給stat

  2. chdir到目錄中。