WHCSRL 技术网

34. Linux link和ulink隐式回收

给文件创建硬链接

sudo ln a.c a.hard

 下面使用link函数创建硬链接的功能

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

实现mv的功能:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. int main(int argc,char *argv[])
  5. {
  6. link(argv[1],argv[2]);
  7. unlink(argv[1]);
  8. return 0;
  9. }

 

unlink函数删除硬链接文件

 unlink函数

删除一个文件的目录项:

int unlink(const char *pathname);

成功:0;

失败:-1;

设置errno为相应值

练习:编程实现mv命令的改名操作

注意Linux下删除文件的机制:不断将st_link  -1,直至减为零为止,无目录项对应的文件,将会被操作系统择机释放。(具体时间由系统内部调度算法决定)

因此,我们删除文件,从某种意义上说,只是让文件具备了被释放的条件。

unlink函数的特征:清除文件时,如果文件的硬链接数到0了,没有dentry(目录项)对应,但该文件仍不会马上被释放。要等到所有打开该文件的进程关闭该文件系统才会挑时间将该文件释放掉。

  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6. int main(void)
  7. {
  8. int fd,ret;
  9. char *p = "test of unlink ";
  10. char *p1 = "after write something. ";
  11. fd = open("temp.txt",O_RDWR|O_CREAT|O_TRUNC,0777);
  12. if(fd < 0)
  13. {
  14. perror("open temp error");
  15. exit(1);
  16. }
  17. ret = write(fd,p,strlen(p));//往temp.txt里面写东西
  18. if(ret == -1)
  19. {
  20. perror("-------write error");
  21. }
  22. printf("hi! I'm printf ");
  23. ret = write(fd,p1,strlen(p1)); //往temp.txt里面写东西
  24. if(ret == -1)
  25. {
  26. perror("-------write error");
  27. }
  28. printf("Enter anykey continue ");
  29. getchar(); //阻塞作用
  30. close(fd);
  31. ret = unlink("temp.txt"); //到了这一步删除temp.txt文件
  32. if(ret < 0)
  33. {
  34. perror("unlink error");
  35. exit(1);
  36. }
  37. return 0;
  38. } 1,8 Top

 在文件写入前删除文件

  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6. int main(void)
  7. {
  8. int fd,ret;
  9. char *p = "test of unlink ";
  10. char *p1 = "after write something. ";
  11. fd = open("temp.txt",O_RDWR|O_CREAT|O_TRUNC,0777);
  12. if(fd < 0)
  13. {
  14. perror("open temp error");
  15. exit(1);
  16. }
  17. ret = unlink("temp.txt");
  18. if(ret < 0)
  19. {
  20. perror("unlink error");
  21. exit(1);
  22. }
  23. ret = write(fd,p,strlen(p));
  24. if(ret == -1)
  25. {
  26. perror("-------write error");
  27. }
  28. printf("hi! I'm printf ");
  29. ret = write(fd,p1,strlen(p1));
  30. if(ret == -1)
  31. {
  32. perror("-------write error");
  33. }
  34. printf("Enter anykey continue ");
  35. getchar();
  36. p[1]='a';
  37. close(fd);
  38. return 0;
  39. }

把内容放到了缓冲区中,等进程结束了就释放了。

隐式回收

        当进程结束运行时,所有该进程打开的文件会被关闭,申请的内存空间会被释放。系统的这一特性称之为隐式回收系统资源。

symlink函数

创建一个符号链接

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

成功:0;

失败:-1

设置errno为相应值

创建软连接

 sudo ln -s test t.soft

读符号链接文件本身

readlink函数

读取符号链接文件本身内容,得到链接所指向的文件名。

ssize_t readlink(const char *path,char *buf,size_t bufsize);

成功:0

失败:-1

设置errno为相应值

rename函数

重命名一个文件。

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

成功:0

失败:-1

设置errno为相应值

文件目录rwx权限差异

 sudo chmod a-x unlink.c

删除执行权限(x)

opendir函数

根据传入的目录名打开一个目录(库函数)

DIR *opendir(const char name);       

  成功返回指向该目录结构体指针

  失败返回NULL

参数支持相对路径、绝对路径两种方式:例如:打开当前目录:①getcwd(),opendir()

②opendir(".");(库函数) 

closedir函数

需要包含头文件#include <dirent.h>

函数原型:

int closedir(DIR *dirp); 

readdir函数

函数原型:

struct dirent *readdir(DIR *dirp);

 

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <dirent.h>
  6. int main(int argc,char *argv[])
  7. {
  8. DIR *dp;
  9. struct dirent *sdp;
  10. dp = opendir(argv[1]);
  11. if(dp == NULL)
  12. {
  13. perror("opendir error");
  14. exit(1);
  15. }
  16. while((sdp=readdir(dp))!=NULL)
  17. {
  18. printf("%%%%%%%%s ",sdp->d_name); //读取到的名字
  19. }
  20. printf(" ");
  21. closedir(dp);
  22. return 0;
  23. }

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <dirent.h>
  6. int main(int argc,char *argv[])
  7. {
  8. DIR *dp;
  9. struct dirent *sdp;
  10. dp = opendir(argv[1]);
  11. if(dp == NULL)
  12. {
  13. perror("opendir error");
  14. exit(1);
  15. }
  16. while((sdp=readdir(dp))!=NULL)
  17. {
  18. if(strcmp(sdp->d_name ,".") == 0) //读取文件名,当.的时候,继续执行循环
  19. continue;
  20. else if(strcmp(sdp->d_name ,"..") == 0) //
  21. continue;
  22. printf("%%%%%%%%s ",sdp->d_name);
  23. }
  24. printf(" ");
  25. closedir(dp);
  26. return 0;
  27. }
推荐阅读