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);
相关推荐
ZHOUPUYU14 小时前
PHP 8.3网关优化:我用JIT将QPS提升300%的真实踩坑录
开发语言·php
寻寻觅觅☆18 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
时代的凡人18 小时前
0208晨间笔记
笔记
YJlio18 小时前
1.7 通过 Sysinternals Live 在线运行工具:不下载也能用的“云端工具箱”
c语言·网络·python·数码相机·ios·django·iphone
l1t18 小时前
在wsl的python 3.14.3容器中使用databend包
开发语言·数据库·python·databend
小白同学_C18 小时前
Lab4-Lab: traps && MIT6.1810操作系统工程【持续更新】 _
linux·c/c++·操作系统os
今天只学一颗糖18 小时前
1、《深入理解计算机系统》--计算机系统介绍
linux·笔记·学习·系统架构
赶路人儿19 小时前
Jsoniter(java版本)使用介绍
java·开发语言
ceclar12319 小时前
C++使用format
开发语言·c++·算法
码说AI20 小时前
python快速绘制走势图对比曲线
开发语言·python