2012-02-01 169 views
0

我有一個簡單的例子:如何知道在重命名期間哪個文件失敗?

#include <stdio.h> 
#include <errno.h> 

int main() { 
    int result = rename("filea", "doesntexist/fileb"); 
    if (result != 0) { 
    printf("NOOOO %d\n", errno); 
    } 
    return 0; 
} 

和我想要的可能的故障的2之間進行區分:

  1. filea中不存在
  2. 目錄FILEB不存在

但它總是返回errno = 2當任何一個不存在時... uhm 任何想法我怎麼能解決這個問題?

感謝

編輯:如果可能的話,如果不存在的文件手動檢查。

EDIT2:不檢查文件是否存在是一個愚蠢的約束;)所以,我已經接受了其中一個答案。謝謝!

回答

1

我不知道你將如何檢查文件是否存在,不檢查文件是否存在,但希望這個功能將會幫助你:

#include <sys/stat.h> 

if (!fileExists("foo")) { /* foo does not exist */ } 

int fileExists (const char *fn) 
{ 
    struct stat buf; 
    int i = stat(fn, &buf); 
    if (i == 0) 
     return 1; /* file found */ 
    return 0; 
} 

如果你的目標是保持代碼乾淨,那麼就使用功能:

int main() 
{ 
    if (! renameFiles("fileA", "fileB")) { 
     fprintf(stderr, "rename failed...\n"); 
     exit EXIT_FAILURE; 
    } 
    return EXIT_SUCCESS; 
} 

int renameFiles(const char *source, const char *destination) 
{ 
    int result = -1; 

    if ((fileExists(source)) && (!fileExists(destination))) 
     result = rename(source, destination); 

    if (result == 0) 
     return 1; /* rename succeeded */ 

    /* 
     Either `source` does not exist, or `destination` 
     already exists, or there is some other error (take 
     a look at `errno` and handle appropriately) 
    */ 

    return 0; 
} 

你可以從renameFiles()返回自定義錯誤代碼和有條件地處理基於哪個文件或不存在,或有其他問題與rename()調用錯誤。

+0

很抱歉,在重命名之前檢查文件是否存在效率低下。原來的問題很明顯,如果重命名失敗,這只是一個問題。 – Fred 2012-02-02 14:10:11

1

先致電access()(unistd.h)。或者stat()。當filea不存在時,您可能會收到ENOENT錯誤。有些方法可以在FILEB得到一個錯誤:

  1. 路徑無法找到
  2. FILEB存在的道路上沒有任何權限,你沒有權限
  3. 你有過長或畸形名

還有其他人,但他們不是很常見。

在fileB不存在的情況下,您不應該遇到錯誤。你執行一個mv文件fileb(重命名),並且mv的所有錯誤都適用於此處。缺少目標文件不是其中之一。

你也應該有

#include <errno.h> 

因爲你參考errno

+0

對不起,通過fileb不存在我的意思是,我要移動到的目錄,它也返回ENOENT – DiogoNeves 2012-02-01 22:58:37

+0

再次,這是效率低下,請參閱上面的評論。 – Fred 2012-02-02 14:11:33

0

如果errno總是2 ENOENT「沒有這樣的文件或目錄」在您的系統上,您將要檢查是否存在某些東西。在我的系統上,如果舊的不存在,或者如果新的的目錄路徑不存在,則在我的系統上獲得2的errno。

但是還有更多的2個可能的錯誤。鏈接http://man.chinaunix.net/unix/susv3/functions/rename.html有20個不同的errno值指定。

我會建議,如果重命名失敗,錯誤號是2,然後檢查是否存在。如果找到,則問題是在中指定的目錄不存在。

1

如果出現錯誤,ISO C標準甚至不要求庫函數rename設置errno。所有保證的是錯誤時的非零返回值(7.19.4.2,§3)。

所以這是否可能取決於你的平臺(而且它不是便攜式的)。

E.g.在Linux中,無法通過在rename(根據this man page)後查看errno來區分它們中的哪些丟失。