zoukankan      html  css  js  c++  java
  • 文件和目录之link、unlink、remove和rename函数

    任何一个文件可以有多个目录项指向其i节点。创建一个指向现有文件的链接的方法是使用link函数。

    #include <unistd.h>
    int link( const char *existingpath, const char *newpath );
    返回值:若成功返回0,若出错返回-1

    此函数创建一个新目录项newpath,它引用现有的文件existingpath。如若newpath已经存在,则返回出错。只创建newpath中的最后一个分量,路径中的其他部分应当已经存在。

    创建新目录项以及增加链接计数应当是个原子操作。虽然POSIX.1允许实现支持跨文件系统的链接,但是大多数实现要求这两个路径名在同一个文件系统中。如果实现支持创建指向一个目录的硬链接,那么也仅限于超级用户才可以这样做。其理由是这样做可能在文件系统中形成循环,大多数处理文件系统的实用程序都不能处理这种情况。因此很多文件系统实现不允许对目录的硬链接。

    为了删除一个现有的目录项,可以调用unlink函数。

    #include <unistd.h>
    int unlink( const char *pathname );
    返回值:若成功则返回0,若出错则返回-1

    此函数删除目录项,并将由pathname所引用文件的链接计数减1。如果还有指向该文件的其他链接,则仍可通过其他链接访问该文件的数据。如果出错,则不对该文件做任何更改。

    为了解除对文件的链接,必须对包含该目录项的目录具有写和执行的权限。如果对该目录设置了粘住位,则对该目录必须具有写权限,并且具备下面三个条件之一:

    拥有该文件。

    拥有该目录。

    具有超级用户特权。

    只有当链接计数达到0时,该文件的内容才可被删除。另一个条件也会阻止删除文件的内容——只要有进程打开了该文件,其内容也不能删除。关闭一个文件时,内核首先检查打开该文件的进程数。如果该数达到0,然后内核检查其链接数,如果这个数也是0,那么就删除该文件的内容。

    程序清单4-5 打开一个文件,然后unlink它

    [root@localhost apue]# cat prog4-5.c
    #include "apue.h"
    #include <fcntl.h>
    
    int 
    main(void)
    {
            if(open("tempfile", O_RDWR) < 0)
                    err_sys("open error");
            if(unlink("tempfile") < 0)
                    err_sys("unlink error");
            printf("file unlinked
    ");
            sleep(15);
            printf("done
    ");
            exit(0);
    }

    运行该程序,其结果是:

    [root@localhost apue]# ls -l tempfile
    -rw-r--r-- 1 root root 38117937 01-02 18:18 tempfile
    [root@localhost apue]# df /home
    文件系统               1K-块        已用     可用      已用% 挂载点
    /dev/sda3         15289132   
    209228
      14290712   2% /home
    [root@localhost apue]# ./prog4-5 &
    [1] 5152
    [root@localhost apue]# file unlinked
    [root@localhost apue]# ls -l tempfile
    ls: tempfile: 没有那个文件或目录                                                                         此时,目录项已删除
    [root@localhost apue]# df /home
    文件系统               1K-块        已用     可用      已用% 挂载点
    /dev/sda3         15289132    209228  14290712   2% /home                                   从已用/可用空间可以看出该文件内容还没有删除
    [root@localhost apue]# done
    [root@localhost apue]# df /home
    文件系统               1K-块        已用     可用      已用% 挂载点
    /dev/sda3         15289132    171956  14327984   2% /home                                   睡眠结束后,进程结束,此时才删除了该文件内容

    unlink的这种性质经常被程序用来确保即使是在该程序崩溃时,它所创建的临时文件也不会遗留下来。进程用open或creat创建一个文件,然后立即调用unlink。因为该文件仍旧是打开的,所以不会将其内容删除。只有当进程关闭该文件或终止时(在这种情况下,内核会关闭该进程打开的全部文件),该文件的内容才会被删除。

    如果pathname是符号链接,那么unlink删除该符号链接,而不会删除由该链接所引用的文件。给出符号链接名情况下,没有一个函数能删除由该链接所引用的文件。

    超级用户可以调用unlink,其参数pathname指定一个目录,但是通常应当使用rmdir函数,而不是使用这种方式。

    我们也可以用remove函数解除对一个文件或目录的链接。对于文件,remove的功能与unlink相同。对于目录,remove的功能与rmdir相同。

    #include <stdio.h>
    int remove( const char *pathname);
    返回值:若成功则返回0,若出错则返回-1

    文件或目录用rename函数更名。

    #include <stdio.h>
    int rename( const char *oldname, const char *newname );
    返回值:若成功则返回0,若出错则返回-1

    根据oldname是指文件还是目录,有几种情况要加以说明。我们也应说明如果newname已经存在将会发生什么。

    (1)如果oldname指的是一个文件而不是目录,那么为该文件或符号链接更名。在这种情况下,如果newname已存在,则它不能引用一个目录。如果newname已存在,而且不是一个目录,则先将该目录项删除然后将oldname更名为newname。对包含oldname的目录以及包含newname的目录,调用进程必须具有写权限,因为将更改这两个目录。

    (2)如果oldname指的是一个目录,那么为该目录更名。如果newname已存在,则它必须引用一个目录,而且该目录应当是空目录(空目录指的是该目录中只有.和..项)。如果newname存在(而且是一个空目录),则先将其删除,然后将oldname更名为newname。另外,当为一个目录更名时,newname不能包含oldname作为其路径前缀。例如,不能将/usr/foo更名为/usr/foo/testdir,因为旧名字(/usr/foo)是新名字的路径前缀,因而不能将其删除。

    (3)如若oldname或newname引用符号链接,则处理的是符号链接本身,而不是它所引用的文件。

    (4)作为一个特例,如果oldname和newname引用同一文件,则函数不做任何更改而成功返回。

    如若newname已经存在,则调用进程对它需要有写权限(如同删除情况一样)。另外,调用进程将删除oldname目录项,并可能要创建newname目录项,所以它需要对包含oldname以及newname的目录具有写和执行权限。

    本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/

  • 相关阅读:
    asp.net core3.1修改代码以支持windows服务发布
    .NET Core3.1IFreeSql使用FreeSql.Generator自动生成实体类
    西南大学2021年秋《线性代数》参考答案
    西南大学2021年秋形势与政策2 阶段一参考答案
    送给程序员的礼物
    西南大学2021年秋形势与政策2 阶段三参考答案
    拿 M 奖真的那么难吗?这份美赛攻略请收下!
    前端开发必会实战项目,Vue Router 实战来啦!​​
    你喜欢哪款 Linux 桌面?萝莉风?御姐风?
    Python 挑战,你通关了吗?速来看题解!
  • 原文地址:https://www.cnblogs.com/nufangrensheng/p/3503320.html
Copyright © 2011-2022 走看看