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);
相关推荐
zhangfeng113327 分钟前
openclaw skills 小龙虾技能 通讯仿真 matlab skill Simulink Agentic Toolkit,通过kimi找到,mcp通讯
开发语言·matlab·openclaw·通讯仿真
chao1898447 小时前
基于 SPEA2 的多目标优化算法 MATLAB 实现
开发语言·算法·matlab
赏金术士7 小时前
Kotlin 习题集 · 高级篇
android·开发语言·kotlin
原来是猿8 小时前
网络计算器:理解序列化与反序列化(中)
linux·运维·服务器·网络·tcp/ip
楼兰公子8 小时前
buildroot 在编译rust时裁剪平台类型数量的方法
开发语言·后端·rust
知识领航员8 小时前
蘑兔AI音乐深度实测:功能拆解、实测表现与适用场景
java·c语言·c++·人工智能·python·算法·github
薛定e的猫咪9 小时前
因果推理研究方向综述笔记
人工智能·笔记·深度学习·算法
AOwhisky9 小时前
虚拟化技术学习笔记
linux·运维·笔记·学习·虚拟化技术
吴声子夜歌9 小时前
Go——并发编程
开发语言·后端·golang
一只机电自动化菜鸟9 小时前
一建机电备考笔记(33) 机电专业技术(起重技术-吊装方案)(含考频+题型)
经验分享·笔记·学习·职场和发展·课程设计