文件和目录之link、unlink、remove和rename函数

时间:2022-09-18 19:47:15

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

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

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

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

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

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

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

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

拥有该文件。

拥有该目录。

具有超级用户特权。

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

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

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

运行该程序,其结果是:

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

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

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

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

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

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

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

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

根据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/

文件和目录之link、unlink、remove和rename函数的更多相关文章

  1. link&comma;unlink&comma;remove&comma; rename函数

    link函数:创建一个指向现有文件的链接的方法是使用 个人理解为cp命令 #include <unistd.h> int link( const char *existingpath, c ...

  2. 文件和目录之chdir、fchdir和getcwd函数

    每个进程都有一个当前工作目录,此目录是搜索所有相对路径名的起点(不以斜杠开始的路径名为相对路径名).当用户登录到UNIX系统时,其当前工作目录通常是口令文件(/etc/passwd)中该用户登录项的第 ...

  3. Python--遍历文件夹下所有文件和目录的方法(os&period;walk&lpar;rootdir&rpar;函数返回一个三元素元祖)

    import os import os.path # This folder is custom rootdir = '/Users/macbookpro/Desktop/test' for pare ...

  4. 文件和目录之stat、fstat和lstat函数

    #include <sys/stat.h> int stat( const char *restrict pathname, struct stat *restrict buf ); in ...

  5. 文件和目录之chown、fchown和lchown函数

    下面几个chown函数可用于更改文件的用户ID和组ID. #include <unistd.h> int chown( const char *pathname, uid_t owner, ...

  6. UNIX系统高级编程——第四章-文件和目录-总结

    文件系统: 以UNIX系统V文件系统为例: 磁盘分为区,每个分区都有自己的文件系统: ​ i节点是固定长度的记录项,包含了文件的相关信息.目录项包含文件名和i节点号.stat结构中除文件名和i节点编号 ...

  7. &lbrack;置顶&rsqb; 文件和目录(二)--unix环境高级编程读书笔记

    在linux中,文件的相关信息都记录在stat这个结构体中,文件长度是记录在stat的st_size成员中.对于普通文件,其长度可以为0,目录的长度一般为1024的倍数,这与linux文件系统中blo ...

  8. linux系统学习笔记:文件、目录、用户

    本篇主要从stat函数开始,逐个说明stat结构的每一个成员,以此来了解文件的所有属性.同时将说明修改这个属性的各个函数. 一.文件 使用stat函数族得到和文件有关的信息结构. #include & ...

  9. Python中的文件和目录操作实现

    Python中的文件和目录操作实现 对于文件和目录的处理,虽然可以通过操作系统命令来完成,但是Python语言为了便于开发人员以编程的方式处理相关工作,提供了许多处理文件和目录的内置函数.重要的是,这 ...

随机推荐

  1. 第二轮冲刺-Runner站立会议07

    今天:实现日历界面 明天:优化日历界面

  2. LeetCode &quot&semi;Design Twitter&quot&semi;

    A mix of hashmap, list and heap. struct Tw { Tw(long long pts, int tid) { ts = pts; tweetid = tid; } ...

  3. 微软BI 之SSRS 系列 - 巧用 RunningValue 函数在分组中排序并设置 RANK 排名

    开篇介绍 经常有像类似于这样的排序需求,以及设置分组下的排序序号.比如此图中要求城市 City 在省份下按照 Internet Sales Amount 总销售额进行排序,并标识在各省份下的排名. 实 ...

  4. poj 1265 Area&lpar; pick 定理 &rpar;

    题目:http://poj.org/problem?id=1265 题意:已知机器人行走步数及每一步的坐标   变化量 ,求机器人所走路径围成的多边形的面积.多边形边上和内部的点的数量. 思路:1.以 ...

  5. hdu 4585 Shaolin&lowbar;set用法

    题目链接 题意:有n个人想成为少林,但是成为少林必须跟少林的大师大一场,当然要选择战斗力很近的,有两大师战斗力跟那人相近程度一样就选战斗力小的那个,按输入顺序,先输入的人先成为少林大师,后面输入的人, ...

  6. firefox同步数据时无响应问题

    之前设置了firefox的数据同步,可以在不同电脑上,同步自己的书签等信息,感觉很方便实用,最近在点工具立即同步时,不报错,书签也没有同步,没有任何响应: 后来查了许多网上资料,都不见效,无意间看到 ...

  7. 微信小程序开发的游戏《拼图游戏》

    微信小程序开发的游戏<拼图游戏> 代码直接考进去就能用 pintu.js // pintu.js Page({ /** * 页面的初始数据 */ data: { }, initGame: ...

  8. JAVA8 Stream集合操作:中间方法和完结方法

    StreamLambda为java8带了闭包,这一特性在集合操作中尤为重要:java8中支持对集合对象的stream进行函数式操作,此外,stream api也被集成进了collection api, ...

  9. keil安装

    安装准备: 一个keil安装程序,一个注册机 安装步骤.... 软件安装: 打开C51V901.EXE 安装程序 点击Next, 同意上述证书协议 重复点击Next,知道出现finish停下. 3个多 ...

  10. x-pack

    x-pack安装>官网安装步骤https://www.elastic.co/downloads/x-pack >x-pack简介X-Pack是一个Elastic Stack的扩展,将安全, ...