zoukankan      html  css  js  c++  java
  • Linux中link,unlink,close,fclose详解

    每一个文件,都可以通过一个struct stat的结构体来获得文件信息,其中一个成员st_nlink代表文件的链接数。
           当通过shell的touch命令或者在程序中open一个带有O_CREAT的不存在的文件时,文件的链接数为1。

           通常open一个已存在的文件不会影响文件的链接数。open的作用只是使调用进程与文件之间建立一种访问关系,即open之后返回fd,调用进程可以通过fd来read 、write 、 ftruncate等等一系列对文件的操作。
           close()就是消除这种调用进程与文件之间的访问关系。自然,不会影响文件的链接数。在调用close时,内核会检查打开该文件的进程数,如果此数为0,进一步检查文件的链接数,如果这个数也为0,那么就删除文件内容。

           link函数创建一个新目录项,并且增加一个链接数。
           unlink函数删除目录项,并且减少一个链接数。如果链接数达到0并且没有任何进程打开该文件,该文件内容才被真正删除。如果在unlilnk之前没有close,那么依旧可以访问文件内容。
      
           综上所诉,真正影响链接数的操作是link、unlink以及open的创建。
           删除文件内容的真正含义是文件的链接数为0,而这个操作的本质完成者是unlink。close能够实施删除文件内容的操作,必定是因为在close之前有一个unlink操作。

          举个例子简单说明:

    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<fcntl.h>
    #include<unistd.h>
    
    int main()
    {
        int fd;
        //char buf[32];
        struct stat buf;
    
    //没有打开文件之前线测试链接数
        if(stat("abc", &buf) !=0)
            printf("stat file fail 
    ");
        printf("1. link =%d 
    ", buf.st_nlink);
    
        //打开已经存在的abc
        fd = open("abc", O_RDONLY);
        stat("abc", &buf);
        printf("2. link =%d 
    ", buf.st_nlink);
    
        //关闭文件测试链接数
        close(fd);
        stat("abc", &buf);
        printf("3. link =%d 
    ", buf.st_nlink);
    
        //创建硬链接,测试链接数
        if(link("abc", "abc1"))
            printf("link abc fail
    ");
        stat("abc", &buf);
        printf("4. link =%d 
    ", buf.st_nlink);
    
        //删除abc1,测试链接数
        if(unlink("abc1") == 0)
            printf("	delete abc1
    ");
        stat("abc", &buf);
        printf("5. link =%d 
    ", buf.st_nlink);
    
        //重复步骤2
        fd = open("abc", O_RDONLY);
        stat("abc", &buf);
        printf("2. link =%d 
    ", buf.st_nlink);
    
        //删除abc
        if(unlink("abc") == 0)
            printf("	delete abc
    ");
        fstat(fd, &buf);
        printf("7. link =%d 
    ", buf.st_nlink);
    
        close(fd);
        return 0;
    }

    为保证有abc,先执行: touch abc, 然后编译运行:

    1. link =1 
    2. link =1 
    3. link =1 
    4. link =2 
        delete abc1
    5. link =1 
    2. link =1 
        delete abc
    7. link =0 
  • 相关阅读:
    MongoDB Schema Design
    WinDBG中的poi是做什么用的?
    如何在Visual Studio中运行和调试汇编代码?
    [翻译图书] 未完工 Moving Applications to the Cloud on the Microsoft Windows Azure Platform 4
    在Word中生成随机的样本文本
    Quiz Win32内存表示与数值大小
    rep stos dword ptr es:[edi] 是做什么的?
    Windows Azure中虚拟机无法启动, 报错RoleStateUnknown的解决方案
    COM基础介绍
    64位的dump里如何寻找第一个到第四个参数?
  • 原文地址:https://www.cnblogs.com/biglucky/p/4636132.html
Copyright © 2011-2022 走看看