linux系统编程&&文件IO

文件IO --- 系统调用<fcntl.h>

2.1缓存的设计

缓存设计的目的提高效率本质上来说 --- 缓存其实就是一块内存空间

使用gdb查看,FILE结构体,或使用写入数据测试缓冲区。

缓冲区的大小是可以设置

  • Linux 标准 I/O 缓存分三类:交互场景行缓存、文件场景全缓存、出错场景不缓存,适配不同场景的实时性与效率需求;
  • <是输入重定向(读文件)、>是输出重定向(覆盖写文件),是 Linux Shell 中修改程序 I/O 源的基础用法。
cs 复制代码
   int feof(FILE *stream);
检查函数是否真的到达EOF;如果真的出错,函数返回真
   int ferror(FILE *stream);
检查函数是否真的出错;如果真的出错,函数返回真

2.2标准IO和文件IO

复制代码
库函数: //标准IO
     优点:
         a.方便,功能多 
         b.可移植性好 
           标准 
     不足:
         c.可能存在 安全性 隐患
​
系统调用:
     优点:
         a.使用起来,简单 ,功能简单
         b.安全性高 
         c.设备文件 ---- 文件IO    ///dev/video0 ----> fopen();    
     缺点:
         c.很多复杂功能需要自己封装设计
         d.可移植性差 

2.3系统默认打开的文件描述符

  • 系统启动后会默认打开这 3 个文件描述符 ,数值0、1、2是固定且唯一的,不能被随意占用。

  • stdin 负责接收输入、stdout 负责正常输出,而 stderr 是独立的错误输出通道,即使 stdout 被重定向,stderr 仍可单独输出错误信息到屏幕。

  • 三个描述符是 Linux/Unix 系统 IO 操作的基础,所有终端交互的输入输出本质上都是对这三个描述符的操作。

2.3.1打开

open函数

cs 复制代码
#include <fcntl.h>
int open(const char *pathname,int flags);
int open(const char *pathname,int flags,mode_t mode);
    功能:
        打开或创建文件
   
    参数:
        @pathname  //打开的文件名
        @flags     //操作的标志,指定访问模式
             
             //必选
             O_RDONLY  //只读
             O_WRONLY  //只写 
             O_RDWR    //读写 
             
            //附加
            O_APPEND  //追加 
            O_CREAT   //文件不存在 创建 
            O_TRUNC   //文件存在  截短为0 
                 
         @mode     一般不用
         当flags中使用了 O_CREAT 时,需要指定 mode   
            mode 0777
                 0666
                 0444                
     返回值:
            成功 文件描述符
            失败 -1 && errno会被设置 

2.3.2关闭

close函数

cs 复制代码
int close(int fd);
功能:
   关闭文件描述符
   以便 再次使用 
参数:
  @fd  要关闭的文件描述符
返回值:
  成功 0
  失败 -1 
  
文件描述符:
1.非负整型数值 
2.分配原则
  最小未使用   
3.范围 
  0~1023 

2.3.3读写

read函数

cs 复制代码
#include <unistd.h>
ssize_t  read(int fd,      void *buf, size_t count);
功能: 
    从fd中读数据 ,存到 buf中 
参数:
   @fd 要读取的文件 
   @buf 存放读取到的数据的 内存空间 
   @count 一次要读取的数量(字节)
返回值:
   成功 表示成功读到的字节数 
   失败 -1 && errno 
   
   读取结束:
      0 表示到达文件结尾

write函数

cs 复制代码
ssize_t write(int fd,const void *buf, size_t count);
功能: 
    把buf中 写到fd中 
参数:
   @fd    要写入的文件 
   @buf   存放数据的 内存空间 
   @count 一次要写入的数量(字节)
返回值:
   成功 表示成功写入的字节数 
   失败 -1 && errno 

2.3.4常用函数

lseek

cs 复制代码
off_t lseek(int fd, off_t offset, int whence);
功能:
     重新定位文件偏移量 
参数:
    @fd      要定位的文件 
    @offset  偏移量 
    @whence  参考点 
               SEEK_SET //相对于文件开头的 
                  offset >=0 
               SEEK_CUR //相对于当前位置
                  offset>=0
                  offset<0   //不能超过这个文件开头
               SEEK_END //相对于文件末尾 
                  offset < 0  //不能超过这个文件开头
                  offset >= 0 //可以  --- 创建 空洞 文件
   
返回值:
   成功 从头的偏移量
   失败  -1 && errno
       
注意:
    1、不支持O_APPEND的追加模式,无法生成空洞文件。
    2、lseek函数执行失败,文件指针还在偏移前的位置。
    3、lseek函数在设备文件上偏移无效。 /dev/video0 
    4、fifo,socket 也不支持lseek的操作。
​
lseek(fd,0,SEEK_SET); //定位到文件开头 
lseek(fd,0,SEEK_END);
获得文件长度:
off_t len = lseek(fd,0,SEEK_END); //off_t <=> long int

2.4标准IO操作中 ---系统调用的函数

fdopen()

//将fd 转换 成 FILE *

cs 复制代码
FILE *fdopen(int fd,const char *mode);
功能:
   将fd 转换  成 FILE * 
参数:
   @fd    要操作fd
   @mode  打开的模式
返回值: 
   成功 FILE *
   失败 NULL

fileno()

//将FILE *转换 为 fd

cs 复制代码
int fileno(FILE *stream);
功能:
    将FILE *转换 为 fd
参数:
   @stream  要转换流指针 
返回值:
   成功 fd 
   失败 - && errno   
  
  fd = open(,O_RDONLY);
  FILE *fp = fdopen(fd,"a");
   
   
  int feof(FILE *stream);
int ferror(FILE *stream);
相关推荐
Scott9999HH1 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
Yana.nice2 小时前
Linux 只保留 30 天内日志(find命令删除日志文件)
linux·运维·chrome
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海2 小时前
python 列表、元组、集合和字典
开发语言·python
克里斯蒂亚诺更新3 小时前
ruoyi角色权限的对应关系
笔记
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
马优晨4 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
a1117765 小时前
2FA 验证码生成器(github登录验证 app)
笔记·学习
DFT计算杂谈6 小时前
无 Root 权限在 Tesla K80 零门槛部署 DeepSeek 大模型
linux·服务器·网络·数据库·机器学习
人邮异步社区6 小时前
怎么把C语言学到精通?
c语言·开发语言