天天看點

APUE-檔案和目錄(五)函數rename和renameat

rename和renameat

#include <stdio.h>
int rename(const char *oldname,const char*newname);
int renameat(int oldfd,const char *oldname,int newfd, const char *newname);
 成功傳回0;失敗傳回-1           

看下面一段代碼,讓我們對rename做一下測試:

#include <stdio.h>

int main(int args,char *argv[])
{
    if(args!=3)
        printf("The parameter number is not correct!");
    int rv = rename(argv[1],argv[2]);
    if(rv<0)
        err_sys("rename error");
    else
        printf("rename success!\n")
}
           

oldname是一個檔案

  • oldname 是一個檔案,newname不能是已經存在的一個目錄。
[harlan@pes1 myexamples]$ touch 1.txt
[harlan@pes1 myexamples]$ mkdir dir
[harlan@pes1 myexamples]$ ./a.out 1.txt dir
rename error: Is a directory           

可以看到,重命名失敗。

  • oldname是一個檔案,newname存在,并且是一個檔案,rename執行成功。看下面的例子,1.txt大小為0byte,2.txt為27bytes。
[harlan@pes1 myexamples]$ ll *.txt
-rw-rw-r-- 1 harlan harlan  0 Jun 10 19:34 1.txt
-rw-rw-r-- 1 harlan harlan 27 Jun 10 19:41 2.txt           

執行rename之後,2.txt被删除,1.txt被重命名成2.txt。

[harlan@pes1 myexamples]$ ./a.out 1.txt 2.txt
rename success!
[harlan@pes1 myexamples]$ ll *.txt
-rw-rw-r-- 1 harlan harlan 0 Jun 10 19:34 2.txt
           
  • 調用程序需要對包含oldname和newname的目錄具有寫權限,否則執行失敗。
[pesuser@pes1 myexamples]$ ll a.out
-rwxrwxr-x 1 harlan harlan 16214 Jun 10 19:39 a.out           

其他使用者對a.out沒有寫權限,是以,切換到pesuser使用者執行:

[harlan@pes1 myexamples]$ su pesuser
Password:
[pesuser@pes1 myexamples]$ ll *.txt
total 40
-rw-rw-r-- 1 harlan harlan     0 Jun 10 19:34 2.txt
[pesuser@pes1 myexamples]$ ./a.out 2.txt 3.txt
rename error: Permission denied           

執行失敗,沒有權限。

oldname是一個目錄

  • 如果newname存在,則它必須引用一個目錄,而且該目錄應當是空目錄。這時候會先将newname删除,然後将oldname重命名為newname。
[harlan@pes1 myexamples]$ ls -l | grep dir
drwxrwxr-x 2 harlan harlan  4096 Jun 10 19:36 dir
drwxrwxr-x 2 harlan harlan  4096 Jun 10 19:59 dir2
[harlan@pes1 myexamples]$ ./a.out dir dir2
rename success!
[harlan@pes1 myexamples]$ ls -l | grep dir
drwxrwxr-x 2 harlan harlan  4096 Jun 10 19:36 dir2
           
  • 不能在newname中包含oldname作為其路徑字首。
[harlan@pes1 myexamples]$ ./a.out "/github/APUE/chapter_4/myexamples/dir3" "/github/APUE/chapter_4/myexamples/dir3/test"
rename error: Invalid argument
           

oldname或者newname是符号連結

  • 這時候rename修改的是符号連結本身,而不是它所引用的檔案。
[harlan@pes1 myexamples]$ ln -s 2.txt 3.txt
[harlan@pes1 myexamples]$ ll *.txt
-rw-rw-r-- 1 harlan harlan 0 Jun 10 19:34 2.txt
lrwxrwxrwx 1 harlan harlan 5 Jun 10 20:08 3.txt -> 2.txt
[harlan@pes1 myexamples]$ ./a.out  3.txt 4.txt
rename success!
[harlan@pes1 myexamples]$ ll *.txt
-rw-rw-r-- 1 harlan harlan 0 Jun 10 19:34 2.txt
lrwxrwxrwx 1 harlan harlan 5 Jun 10 20:08 4.txt -> 2.txt
           

特殊情況

  • 不能對.和..重命名。更确切的說,.和..不能出現在oldname和newname的最後部分。
  • 如果oldname和newname引用同一個檔案,則函數不做任何更改而成功傳回。

注意:

如果newname已經存在,則調用程序對它需要有寫權限(如同删除情況一樣)。另外,調用程序将删除oldname目錄項,并可能要建立newname目錄項,是以它需要對包含oldname和包含newname的目錄具有寫和執行權限。

作者:

HarlanC

部落格位址:

http://www.cnblogs.com/harlanc/

個人部落格:

http://www.harlancn.me/

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出,

原文連結

如果覺的部落客寫的可以,收到您的贊會是很大的動力,如果您覺的不好,您可以投反對票,但麻煩您留言寫下問題在哪裡,這樣才能共同進步。謝謝!