之前一直对Linux的文件类型中的 “l” 类型的了解不是很深入,最近经过“圣经”指点,略知一二,在此先记录一下,以便以后查阅,之后会对文件和目录、文件I/O这部分再扩充。

首先需明确,Unix在查阅文件类型时,首先调用的是stat函数,格式如下:

 int  stat(const char *restrict pathname , struct stat *restrictbuf)

   成功则返回0(出错返回-1),得到7种文件类型如下:

1.普通文件 (-)

2.目录文件 (d)

3.块特殊文件 (b)

4.字符特殊文件 (c)

5.FIFO (用于进程间通信,也叫命名管道 )

6.套接字 (socket)

7.符号链接 (l)

平时我们新手接触最多的就是普通文件以及目录文件,同时也会接触到标志为“l”的文件,在此先介绍硬链接和软链接。

硬链接实际上是一个指针,指向源文件的inode,系统并不为它重新分配inode。任何一个文件可以有多个目录项指向其inode,硬链接不会产生新的inode,硬连接不管有多少个,都指向的是同一个inode节点,只是新建一个hard link会把结点连接数增加,只要结点的连接数不是0,文件就一直存在,不管你删除的是源文件还是连接的文件。只要有一个存在,文件就存在(其实就是引用计数的概念)。当你修改源文件或者连接文件任何一个的时候,其他的文件都会做同步的修改。(引自http://blog.csdn.net/yasaken/article/details/7292186)。此时,我们可以试一下,找一个占用磁盘大一些的测试文件,,然后ln建立一个hard link,发现此时该文件的类型就是普通文件,如下图,而且占用同样大的磁盘空间,当我随便去试图修改一个文件时,由于这些硬链接文件指向同一个inode,因此所有文件都做出同步的修改,该文件的链接计数为2,当我们unlink随便一个文件时,链接计数减一,则只删去unlink路径下的那个硬链接文件,实际的文件并没有删除。

通过以上的实验,我个人认为是否可以将硬链接看成是cp一个文件,答案是否定的,因为cp需要占用新的inode节点,并且占用新的磁盘空间,两份文件完全独立开来,而硬链接是创建同一个block的连接,数据只有一份,只不过是有多个inode的关联记录而已,(注意:hard
link只能指向自己文件系统的inode,无法跨越文件系统。如果要想实现支持创建指向一个目录的硬链接,那么也仅限于root,这其实是不被推荐的,容易在文件系统中形成循环。POSIX.1常量LINK_MAX指定了一个文件链接数的最大值为8.)。link 函数以及linkat函数调用方式如下:

int  link (const char *existingpath,  const char *newpath);

   int  linkat (int efd, const char *exsitingpath, int nfd, const char *newpath, int
flag);

   软链接最直观的解释:相当于Windows系统的快捷方式,是一个独立文件(拥有独立的inode,与源文件inode无关),该文件的内容是源文件的路径指针,通过该链接可以访问到源文件。所以删除软链接文件对源文件无影响,但是删除源文件,软链接文件就会找不到要指向的文件(可以类比Windows上快捷方式,你点击快捷方式可以访问某个文件,但是删除快捷方式,对源文件无任何影响)。命令可以用:ln
 -s   源文件的绝对路径   软链接文件的绝对路径

在此注意,指定路径时,一定要指定绝对路径,否则会出现找不到链接的源文件的情况。如下图:软链接已经建立,但是无法通过软链接打开源文件。如果不使用绝对路径的话,就要在脚本中调用linkat函数,通过设置文件描述符efd和nfd的标志为AT_FDCWD(强制通过相对于调用进程的当前目录计算pathname),与相对路径来计算文件的路径(目前我还没有涉及到)。

由于软链接文件与源文件的inode无关,所以是可以跨越文件系统的。同时,软链接的操作权限是777的,但是如果你要对此进行编辑,需要的权限是源文件的权限,而硬链接的操作权限与源文件保持一致。

下面说一下由此引发的对unlink的一点记录。

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

int  unlink (const char *pathname);

int  unlinkat (int fd ,const char *pathname, int flag);

当我们要想删除一个文件时,必须要具备两个条件:

1.链接计数达到0,该文件才可以被删除。

2.只要有进程打开了文件,其内容也不能删除。

如下面一段代码:

int
main(void)
{
if (open("tempfile", O_RDWR|O_CREAT) < 0)
err_sys("open error");
if (unlink("tempfile") < 0)
err_sys("unlink error");
printf("file unlinked\n");
sleep(15);
printf("done\n");
exit(0);
}

当我们执行unlink后,虽然计数为0,实际上并没有将文件删除,而是要经过15秒后的exit(0)使进程调用关闭后,才真正的删除了该文件,正是那句printf让我纠结了大半天。  具体的执行exit(0)做的东西以后再扩充。

从symbol link和hard link 到 unlink函数的一点记录的更多相关文章

  1. Symbolic link and hard link的区别(linux)

    --Symbolic link and hard link的区别(linux) --------------------------------------------------2014/06/10 ...

  2. Expo大作战(八)--expo中的publish以及expo中的link,对link这块东西没有详细看,大家可以来和我交流

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,将全部来与官网 我猜去全部机翻+个人 ...

  3. 菜鸟学Linux - Hard Link与Symbolic Link

    在学习Hard Link与Symbolic Link之前,需要大概了解一下inode与data block.在Linux的文件系统中,一个文件对应一个inode与若干个data block.inode ...

  4. PHP unlink() 函数

    定义和用法 unlink() 函数删除文件. 若成功,则返回 true,失败则返回 false. 语法 unlink(filename,context) 参数 描述 filename 必需.规定要删除 ...

  5. PHP unlink()函数,删除文件

    定义和用法 unlink() 函数删除文件. 若成功,则返回 true,失败则返回 false. 语法 unlink(filename,context) 参数 描述 filename 必需.规定要删除 ...

  6. php unlink()函数使用

    最近在写个网站,需要上传图片,如果修改图片,就图片就没有用了,会占用服务器的硬盘资源,所以想到用unlink函数删除旧照片. 问题 : unlink函数只能删除 相对于函数执行文件的相对目录  或  ...

  7. PHP unlink() 函数(删除文件)

    PHP unlink() 函数(删除文件) 一.总结 unlink() 函数删除文件. 1.实例 $file = "test.txt"; if (!unlink($file)) 2 ...

  8. CSS教程:vlink,alink,link和a:link

    超链接文字的状态可以通过伪类选择符+样式规则来控制. 一组专门的预定义的类称为伪类,主要用来处理超链接的状态.超链接文字的状态可以通过伪类选择符+样式规则来控制.伪类选择符包括: 总: a 表示 超链 ...

  9. VC中LINK 2001 和 LINK 2009 的错误的解决

    最近将两个开源C++项目编译成windows版本的时候遇到很多问题,关键是两个项目经过同事的修改之后,一个项目引用了另一个项目,两个项目的头文件中都有一些跨平台的关于数据类型,以及一些通用函数的定义, ...

随机推荐

  1. LeetCode OJ-- Divide Two Integers *

    https://oj.leetcode.com/problems/divide-two-integers/ 在不使用乘法.除法.求余的情况下计算除法. 使用减法计算,看看减几次. 刚开始寻思朴素的暴力 ...

  2. 八、Ubuntu安装Tomcat和jdk

    1.解压Tomcat 和 jdk tar -zxvf apache-tomcat-8.0.28.tar.gz tar -zxvf jdk-8u60-linux-x64.gz 2.将解压后的tomcat ...

  3. 2016北京集训测试赛(十七)Problem A: crash的游戏

    Solution 相当于要你计算这样一个式子: \[ \sum_{x = 0}^m \left( \begin{array}{} m \\ x \end{array} \right) \left( \ ...

  4. getenv, _wgetenv

    Description The C library function char *getenv(const char *name) searches for the environment strin ...

  5. [译]在IB中实现自动布局

    有关自动布局的其他文章: Autolayout Visual format language for autolayout Creating individual constraints 可怜的界面编 ...

  6. 【spring boot】8.spring boot的日志框架logback使用

    在继续上一篇的Debug调试之后,把spring boot的日志框架使用情况逐步蚕食. 参考:http://tengj.top/2017/04/05/springbo 开篇之前,贴上完整applica ...

  7. python 制作wordcloud词云

    pip install wordcloud 需要用到numpy  pillow matplotlib 安装完成以后 wordcloud_cli --text in.txt --imagefile ou ...

  8. 3、C++新的关键字

        C++ 添加了一些全新的关键字. 1.new     new 来进行动态内存的分配,而delect 则是进行内存的释放, 申请的方式: 变量申请: int *p = new int; // 申 ...

  9. 转:office 2016最新安装及激活教程(KMS)

    office 2016最新安装及激活教程(KMS)[亲测有效]!!   win7激活教程 博主的一个朋友,咳咳……你们懂得,想装office,于是我就上网找了一下激活的方法,亲测有效,而且也没有什么广 ...

  10. 使用Nginx的proxy_cache缓存功能取代Squid

    Nginx从0.7.48版本开始,支持了类似Squid的缓存功能.这个缓存是把URL及相关组合当作Key,用md5编码哈希后保存在硬盘上,所以它可以支持任意URL链接,同时也支持404/301/302 ...