文件系统必备知识点

文件相关系统调用接口:

以open函数调用为例,其打开后返回文件描述符

具体步骤如图:

PCB中fds(文件描述符)专门用来存储已打开的文件,它是一个数组类型

文件表中存储文件的打开标志、当前读写位置、引用计数、指向v节点的指针,v节点中存有指向i节点的指针

在linux下我们ls获取的信息就来自v节点表,i节点表中存放的是磁盘数据的存储位置

引用计数(refcnt):表示有几个文件描述符指向这个文件表,refcnt可能为2,因为子进程拷贝父进程内容时候,会拷贝父进程的文件描述符,此时父子进程的文件描述符指向同一个refcnt。当refcnt==0文件才释放,fclose是让refcnt-1。而一次open就拥有一个文件表,多次open并不影响refcnt

举个例子

接口函数中有一个叫lseek

int  lseek(int fd,off_t offset,int whence);

从指定位置开始读取,返回值为绝对偏移量,可以用来测文件的大小,其中fd为已打开的文件,offset为偏移量,whence为偏移量的基准位置

whence:  SEEK_SET     表示文件的相对起始位置

               SEEK_CUR    表示文件的相对当前位置

               SEEK_END    表示文件的相对结束位置

返回值:新的相对于文件开头的字节数

这个函数的功能时如何实现的呢?它就是通过修改内核文件表中的读写位置达到从指定位置开始读写的。

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include<fcntl.h>
  5 #include<string.h>
  6 int main()
  7 {
  8     int fd=open("test.txt",O_RDONLY);
  9     if(fd==-1)
 10     {
 11         perror("open");
 12         exit(1);
 13     }
 14     while(1)
 15     {
 16         char buf;
 17         int r=read(fd,&buf,1);
 18         if(r<=0)
 19         { 
 20             break;
 21         } 
 22         else
 23         { 
 24             write(1,&buf,1);                                                                                                                             
 25             lseek(fd,1,SEEK_CUR);
 26         }
 27     }
 28     close(fd); 
 29 }
~     

补充一点:read、write时系统给的,fread、fwrite是c库函数里有的,系统中的I/O不带缓存,c库中的I/O带缓存

linux下七种文件类型:

其中套接字、块设备、字符设备、管道时伪文件,不占用磁盘空间

符号链接记录的是路径、路径不长时存在i节点里面

如何获取文件属性:

磁盘存储文件时除了存储文件内容还要存储与文件相关的信息。

我们可以通过ls读取存储在磁盘上的信息显示到用户空间,那么如何单独获取文件属性?

需要掉用stat函数:

引用头文件为:<sys/stat.h>

int  stat(const  char *path,struct stat *buf),指针不带const多半是传出型的参数,这里的buf就是传出型参数,返回的是文件相关信息。

举一个具体的使用例子:求文件大小(我们以st_size可以获取)

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include<sys/stat.h>                                                                                                                                     
  5 int main()
  6 {
  7     struct stat sbuf;
  8     if(stat("./stattest.txt",&sbuf)==-1)
  9     {
 10         perror("stat");
 11         exit(1);
 12     }
 13     else
 14     {
 15         printf("size:%d",sbuf.st_size);
 16     }
 17 }

我们编译执行一下,发现这里的size与我们ls-l获得的size一致:

猜你喜欢

转载自blog.csdn.net/enjoymyselflzz/article/details/81365493
今日推荐