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);
相关推荐
0xDevNull12 小时前
Linux切换JDK版本详细教程
linux
进击的丸子12 小时前
虹软人脸服务器版SDK(Linux/ARM Pro)多线程调用及性能优化
linux·数据库·后端
齐生112 小时前
iOS 知识点 - IAP 是怎样的?
笔记
tingshuo29171 天前
D006 【模板】并查集
笔记
Johny_Zhao2 天前
OpenClaw安装部署教程
linux·人工智能·ai·云计算·系统运维·openclaw
tingshuo29172 天前
S001 【模板】从前缀函数到KMP应用 字符串匹配 字符串周期
笔记
RuoZoe2 天前
重塑WPF辉煌?基于DirectX 12的现代.NET UI框架Jalium
c语言
chlk1233 天前
Linux文件权限完全图解:读懂 ls -l 和 chmod 755 背后的秘密
linux·操作系统
舒一笑3 天前
Ubuntu系统安装CodeX出现问题
linux·后端
改一下配置文件3 天前
Ubuntu24.04安装NVIDIA驱动完整指南(含Secure Boot解决方案)
linux