之前一直对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. 链表ADT的实现

    list.h文件 /*链表的类型声明*/ typedef int ElementType; /* START: fig3_6.txt */ #ifndef _List_H #define _List_ ...

  2. LeetCode OJ-- Divide Two Integers *

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

  3. HDU 1223 还是畅通过程【最小生成树模板】

    还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  4. 【Spring源码解析】—— 简单工厂模式的BeanFactory的超简版实现

    一.什么是简单工厂模式 设计模式的核心是“分工”,通过分工将对象与职责划分的更细化,进而提升系统设计的可扩展性,使其更容易维护. 开闭原则:对扩展开放,对修改关闭:要增加一个新的处理逻辑,可以开一个新 ...

  5. Jmeter脚本两种录制方式

    Jmeter 是一个非常流行的性能测试工具,虽然与LoadRunner相比有很多不足,比如:它结果分析能力没有LoadRunner详细:很它的优点也有很多:   l       开源,他是一款开源的免 ...

  6. 基于WPF系统框架设计(1)-为什么要仿Office2010 Ribbon?

    为什么系统框架设计使用Ribbon导航模式? 这得从Office软件的演变说起.微软为什么最后选择使用Ribbon,也许就是很多系统设计要使用Ribbon做功能导航的原因. 你是否还记得曾经使用过的M ...

  7. hibernate多对一单向配置

    查看:http://blog.csdn.net/u010702229/article/details/13170263

  8. GIS可视化

    作为一名GIS专业的学生,一晃也毕业三年了,在supermap也呆了三年多了,做的最多的就是浏览器端的GIS展示,最近也想分享一下我们团队在浏览器端GIS可视化的一些成果,算是做个宣传吧!有用的着的可 ...

  9. hdu 5444 Elven Postman(长春网路赛——平衡二叉树遍历)

    题目链接:pid=5444http://">http://acm.hdu.edu.cn/showproblem.php?pid=5444 Elven Postman Time Limi ...

  10. (转)微信小程序开发项目——笑话大全

    此项目是学习完微信小程序后实现的一个demo,采用聚合数据的免费api获取最新的文本笑话和趣图(图片和gif图)   项目地址:https://github.com/zhijieeeeee/wecha ...