linux中文件描述符、文件操作(open/read/write/close/lseek)、虚拟空间地址、IO缓冲区

一、文件描述符

文件描述符的概念: 在linux系统中打开文件就会获得文件描述符,它是个很小的正整数。每个进程在PCB(进程控制块)中保存着一份文件描述符表,文件描述符就是这个表的索引,每个表项都有一个指向已打开文件的指针。

文件描述符生成: open()、socket()、pipe()等

总结: Fd是文件描述符 ,int类型的索引,标志着一个文件替代指针的使用。open()…等方法返回文件描述符。

二、文件操作函数

函数原型
格式1 int open(const char *pathname, int flags);
格式2 int open(const char *pathname, int flags, mode_t mode);
参数描述
pathname  路径+文件名
flats     操作模式  【参考以下】
mode   当创建文件的时候需要在此位置设置权限
====================================
      flats参数补充说明
 O_CREAT 创建    O_RDONLY只读
 O_WRONLY只写   O_RDWR可读可写
       延伸组合使用
O_RDONLY |O_CREAT 只读如果不存在则创建
O_WRONLY |O_CREAT 只写如果不存在则创建
O_WRONLY | O_APPEND 文件存在则追加写入

====================================
头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
代码举例

  //以只读的方式打开God.txt这个文件
  fd=open("tmp.txt",O_WRONLY)//以追加写入的方式打开tmp.txt 这个文件
  fd=open("tmp.txt",O_WRONLY|O_APPEND);
  //只读的方式打开Fol.txt,若不存在则创建并设置权限为0777(表示可读可写可执行) 
  fd=open("Fol.txt",O_RDONLY|O_CREAT,0777)

函数原型
格式1 int write(int fd, void *buf, int count);
参数描述
fd   表示改文件的文件描述符,open的返回值
buf   写入的文本内容
count  写入的数据长度【使用srtlen非sizeof】
返回值  成功返回写入的字节数 失败返回-1
头文件
#include <unistd.h>
代码举例

 int  fd;
 char text[]="Welcome come to JMU";    
 fd=open("tmp.txt",O_WRONLY|O_CREAT,0777);
 write(fd,text,strlen(buf));

函数原型
int read(int fd, void *buf, size_t count);
参数描述
fd 表示改文件的文件描述符,open的返回值
buf 指缓冲区,读取的数据存放位置
count 传入缓冲区的字节大小【使用sizeof非strlen】
返回值 成功返回读出的字节数 失败返回-1
头文件
#include <unistd.h>
代码举例

 int  fd;
 char buf[20];    
 fd=open("tmp.txt",O_RDONLY);
 read(fd,buf,sizeof(buf));
 //如果要将读取的内容显示 需要自己添加
 printf("读取到内容%s\n",buf);

函数原型
int close(int fd);
参数描述
fd 表示改文件的文件描述符,open的返回值
返回值 成功为0 失败返回-1
头文件
#include <unistd.h>
代码举例

 int  fd;
 fd=open("tmp.txt",O_RDONLY);
 close(fd);

函数原型
int lseek(int fd, off_t offset, int whence);
参数描述
fd   表示改文件的文件描述符,open的返回值
offset  表示偏移量
whence 指出偏移的方式

====================================
        whence参数补充说明
  SEEK_SET:偏移到文件头+ 设置的偏移量
  SEEK_CUR:偏移到当前位置+设置的偏移量
  SEEK_END:偏移到文件尾置+设置的偏移量
        ====================================
头文件
#include <sys/types.h>
#include <unistd.h>
功能描述+代码举例
(1) 返回当前的偏移量

int fd,ret;
fd=open("hello1.txt",O_RDWR);
ret=lseek(fd,0,SEEK_CUR);
printf("%d\n",ret);

(2)返回文件大小

int fd,ret;
fd=open("hello1.txt",O_RDWR);
ret=lseek(fd,0,SEEK_END);
printf("%d\n",ret);

(3)☆扩充文件大小   
特别注意扩充文件大小后 需要写入内容 否则扩充不生效

#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int fd,ret;
char a[]="JMU WELCOME";
fd=open("hello1.txt",O_RDWR|O_CREAT,0777);
ret=lseek(fd,1000,SEEK_END);
write(fd,a,strlen(a));
printf("%d\n",ret);
return 0;
}

使用ls -l 命令可以查看扩充后的字节大小
在这里插入图片描述

三、虚拟空间地址

(1)定义:对于每一个进程,系统都会为其分配一个0-4G的虚拟空间地址,0-3G为用户空间,用户可操作部分。3~4G为内核,其中PCB控制块也存在内核中(补充:每一个进程都有一个PCB)
PCB结构体包括文件标识符表以及其他很多信息
(2)好处
a、方便进程隔离,互补干扰
b、实现虚拟内容,从逻辑上扩大内存,物理上不变
c、方便编译器和操作系统程序隔离

在这里插入图片描述

在这里插入图片描述

四、IO缓冲区

定义:缓冲区就是内存里的一块区域,把数据先存内存里,然后一次性写入硬盘中的文件,类似于数据库的批量操作。
好处:减少对硬盘的直接操作,硬盘的执行速度为毫秒级别,内存为纳秒级别。在硬盘直接操作读写效率太低
如何将缓冲区的的内容存入硬盘文件
(1)刷新缓冲区 fflush
(2)缓冲区满了(自动)
(3)正常关闭文件 1、close 2、return 3、 exit在这里插入图片描述     左边的是File**filename =fopen(file) 中返回的指针所指向的结构体 ,其中包括三部分 fd (文件标识符) 、f_pos、buffer(这边所提到的缓冲区)

猜你喜欢

转载自blog.csdn.net/weixin_44972997/article/details/107327267