浅谈Linux文件操作与文件描述符

一、简单的文件操作与函数介绍

1.open()

系统接口

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname, int flags);

int open(const char *pathname, int flags, mode_t mode);

这里提供了两个接口,根据实际情况选取合适的即可

通过man手册查看mode

在这里插入图片描述

mode指定在创建新文件时使用的权限。当在标志中指定O_CREAT时,必须提供此参数;
没有指定O_CREAT,则忽略模式。创建的文件的权限是(mode&~umask)。请注意,此模式仅适用于新创建的文件的未来访问。

函数参数:

pathname: 要打开或创建的目标文件

flags: 打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成flags

O_RDONLY: 只读打开 O_WRONLY: 只写打开 O_RDWR : 读,写打开前三个常量,必须指定一个且只能指定一个 O_CREAT : 若文件不存在,则创建它,需要使用mode选项,来指明新文件的访问权限 O_APPEND: 追加写 O_TRUNC:清空之前的内容

mode:描述打开文件的权限

函数返回值:

成功返回新的文件描述符,失败返回-1

注意:如果成功,open()返回文件描述符是用于后续系统调用的小的非负整数

2.write()

系统接口

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);

函数参数

fd:要写入文件的文件描述符

buf:将该区域数据写入

size:写入数据的大小

函数返回值

成功返回读取数据大小,失败返回-1,0代表无写入

代码示例:

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>  //write
#include <string.h>  //strlen

int main(){
  int fd = open("./test.txt",O_CREAT | O_WRONLY,0644);
  //读方式打开文件,如果没有则创建
  if(fd < 0){
    perror("open error");
    return -1;
  }
  //打开成功
  printf("打开文件按描述符为:%d\n",fd);
  
  const char* str = "hello fd!\n";
  
  write(fd,str,strlen(str));
  close(fd);
  return 0;
}

先开始没有文件
在这里插入图片描述
运行程序后生成test.txt文件,并且输出文件描述符
在这里插入图片描述
查看文件内容,hello fd!已经写入到文件中在这里插入图片描述

3.read()

系统接口

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);

函数参数

fd:从该文件描述符文件中读取数据

buf:把从fd读取的数据存放在此区域

count:读取数据的大小

函数返回值

成功返回读取数据的大小,失败返回-1,0表示读取到文件的结尾

注意:成功情况下的返回值不一定与count相等

代码示例:

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>  //read
#include <string.h>  //strlen

#define LEN 1024

int main(){
  int fd = open("./test.txt",O_RDONLY);
  if(fd < 0){
    perror("open error");
    return -1;
  }
  char buffer[LEN];
  ssize_t s = read(fd, buffer, sizeof(buffer)-1);
  if(s > 0){
    buffer[s] = 0;//手动设置字符串结尾
    printf("%s\n", buffer);
  }
  close(fd);
  return 0;
}

读取文件内容并输出
在这里插入图片描述

二、文件描述符

在上面我们了解了open,write,read的简单使用。但是,文件在磁盘中被打开的过程是什么呢?接下来就分析一下。

当用户从磁盘打开一个文件,这时候内存中就会形成一个struct file结构,然后从众多文件描述符当中,取最小未分配的文件描述符分配给文件,把struct file的地址存放在fd_array[最小未分配]当中。

示意图:
在这里插入图片描述

从前面的程序也可以看出,新建文件的fd都是从3开始的,什么原因呢?

其实在最开始,OS(操作系统)已经为我们打开了0,1,2号文件描述符,这三个分别是0->stdin, 1->stdout, 2->stderr,我们写个代码验证一下。

#include <stdio.h>
int main(){
  printf("stdin -> %d\n", stdin->_fileno);
  printf("stdout -> %d\n", stdout->_fileno);
  printf("stderr -> %d\n", stderr->_fileno);
  return 0;
}

运行结果如下:

在这里插入图片描述

在了解打开文件过程后,那么我们进行读写操作的时候会发生什么事情呢?

进程进行write,read操作的时候传入fd,这时候进程会在自己的PCB中找到files_struct,在其中找到fd_array[fd]中的内容,读取该内容也就找到了file 的位置,file结构体中有一个file_operations结构里面包含了文件的各种操作,此时就可以对根据需要对文件进行操作了。

示意图:
在这里插入图片描述

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值