zoukankan      html  css  js  c++  java
  • 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!
    ")
    }
    
    

    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的目录具有写和执行权限。

  • 相关阅读:
    org.hibernate.NonUniqueObjectException 原因及解决办法
    Hibernate方法save、update、merge、saveOrUpdate及get和load的区别
    Hibernate实体对象的生命周期(三种状态)
    Java I/O 全面详解
    故障检测、性能调优与Java类加载机制
    Linux基本命令+Makefile
    Redhat9.0+Apache1.3.29+Mysql3.23.58+PHP4.3.4
    u盘安装Linux系统详细教程
    Linux下软件常见安装方式
    Spring MVC 小计
  • 原文地址:https://www.cnblogs.com/harlanc/p/6991035.html
Copyright © 2011-2022 走看看