Unix/Linux编程:更改文件名----rename()

rename()用来改变文件或者目录的位置

  • rename(“y”, “z”); — 改变文件名字
  • rename(“y”, “new/new”); — 改变文件名字和位置
NAME
       rename, renameat, renameat2 - change the name or location of a file

SYNOPSIS
       #include <stdio.h>

       int rename(const char *oldpath, const char *newpath);

rename是如何将一个文件移动到另一个目录的呢?文件实际上不存在目录中,目录中存放的仅仅是它的链接。因此,rename将链接从一个目录移动到另一个目录:
在这里插入图片描述
内核是如何移动这些链接的呢?

  • 复制链接到新的名字/位置
  • 删除原来的链接。

Unix提供了系统调用link()和unlink()来完成这两个操作,因此,rename(“x”, “z”)相当于:

if(link("x", "z") != -1){
	unlink("x");
}

只所以引入rename,是为了避免link和unlink的多线程竞争问题

命令mv就使用了rename()

rename()调用仅操作目录条目,而不移动文件数据。改名既不影响指向该文件的其他硬链接,也不应该持有该文件打开描述符的任何进程,因为这些文件描述符指向的是打开文件描述,(在调用 open()之后)与文件名并无瓜葛

以下规则适用于对rename()的调用

  • 若newpath已经存在,则将其覆盖
  • 若newpath与oldpath指向同一文件,则不发生变化(且调用成功)
  • rename()系统调用对其两个参数中的符号链接均不进行解引用。
    • 如果oldpath是一符号链接,那么将重命名该符号链接
    • 如果newpath是一符号链接,那么将移除已有的符号链接,将其视为由oldpath 重命名而成的普通路径名
  • 如果oldpath是文件而不是目录,那么就不能将newpath指定为一个目录的路径名(否则将 errno 置为 EISDIR)要想重命名一个文件到某一目录中(亦即将文件移到另一目录)newpath 必须包含新的文件名。如下调用既将一个文件移动到另一目录中,同时又将其改名
rename("sub1/x", "sub2/y");
  • 若将oldpath指定为目录名,则意在重命名该目录。
    • 这种情况下,必须保证newpath要么不存在,要么是一个空目录的名称。
    • 无论 newpath 是一个已有文件还是一个非空目录,调用都将出错(分别将 errno 置为 ENOTDIR 和ENOTEMPTY)。
  • 若 oldpath 是一目录,则 newpath 不能包含 oldpath 作为其目录前缀。例如,不能将/home/mtk 重命名为/home/mtk/bin(错误为 EINVAL)。
  • ooldpath 和 newpath 所指代的文件必须位于同一文件系统。之所以如此,是因为目录内容由硬链接列表组成,且硬链接所指向的 i-node 与目录位于同一文件系统。如前所述rename()仅限于操作目录列表的内容。试图将一文件重命名至不同的文件系统将返回错误 EXDEV。(非要如此,必须从一个文件系统中将其文件内容复制到另一文件系统,然后再删除老文件。这正是 mv 命令的功能所在。)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值