嵌入式学习day24----文件编程2

一、缓冲区与标准 I/O

缓冲区设计原则

  • 终端关联:设计行缓存
  • 普通文件:全缓存
  • 出错输出:不缓存

缓冲区在实际发生 I/O 操作时才真正开辟。

行缓存(1024 字节)

刷新条件:

  1. 遇到 \n
  2. 程序正常结束
  3. 缓冲区满
  4. fflush 强制刷新

全缓存(4096 字节)

刷新条件:

  1. 程序正常结束
  2. 缓冲区满
  3. fflush 强制刷新

不缓存

没有缓存,大小为 0。

输出重定向
./a.out > 1.txt   # 输出重定向
./a.out < 1.txt   # 输入重定向

二、标准 I/O 与文件 I/O

标准 I/O(库函数)

  1. 核心概念

    • 抽象一个流(FILE *
    • 设计缓存
    • 封装底层的文件描述符

文件 I/O(系统调用,不带缓冲的 I/O)

1.打开文件:open
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

  • 必选项O_RDONLY(只读)、O_WRONLY(只写)、O_RDWR(读写)
  • 可选项O_APPEND(追加)、O_CREAT(文件不存在则创建)、O_TRUNC(截断为 0)
  • 返回值:成功返回新的文件描述符;失败返回 -1 并设置 errno
fopenopen 的对应关系
fopen("1.txt", "r")   <==> open("1.txt", O_RDONLY);
fopen("1.txt", "r+")  <==> open("1.txt", O_RDWR);
fopen("1.txt", "w")   <==> open("1.txt", O_WRONLY|O_TRUNC|O_CREAT, 0666);
fopen("1.txt", "w+")  <==> open("1.txt", O_RDWR|O_TRUNC|O_CREAT, 0666);
fopen("1.txt", "a")   <==> open("1.txt", O_WRONLY|O_APPEND|O_CREAT, 0666);
fopen("1.txt", "a+")  <==> open("1.txt", O_RDWR|O_APPEND|O_CREAT, 0666);
2.关闭文件:close
int close(int fd);
  • 功能:关闭文件描述符,关闭后该文件描述符可被重复使用
  • 返回值:成功返回 0;失败返回 -1
  • 文件描述符分配原则:最小未使用
3.读写操作:read / write
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
  • read:从 fd 中读取 count 个字节到 buf,成功返回读取到的字节数,读到末尾返回 0
  • write:将 bufcount 个字节写入 fd,成功返回写入的字节数
4.文件定位:lseek
off_t lseek(int fd, off_t offset, int whence);
  • whence 参考点:SEEK_SET(文件开头)、SEEK_CUR(当前位置)、SEEK_END(文件末尾)
  • 常用操作:
    lseek(fd, 0, SEEK_SET);        // 定位到文件开头
    off_t len = lseek(fd, 0, SEEK_END);  // 获取文件大小

    空洞文件:先定位再写入,可创建空洞文件

    lseek(fd, 100-1, SEEK_SET);
    write(fd, "", 1);

    标准 I/O vs 文件 I/O

    类型特点
    标准 I/O库函数,功能丰富、使用方便、可移植性好,需注意缓存与安全性
    文件 I/O系统调用,函数简单,复杂功能需自行封装,可移植性差,安全性较好

    三、混合使用与目录操作

    混合使用

    可以在标准 I/O 和文件 I/O 之间转换:

    FILE *fdopen(int fd, const char *mode);  // 把文件描述符 fd 转换为 FILE*
    int fileno(FILE *stream);                // 把 FILE* 转换为文件描述符 fd

    目录文件操作打开目录:

1.打开目录:opendir
#include <dirent.h>
DIR *opendir(const char *name);
  • 功能:打开目录并创建目录流
  • 返回值:成功返回目录流指针;失败返回 NULL 并设置 errno
2.读取目录项:readdir
struct dirent *readdir(DIR *dirp);
  • 功能:读取目录项
  • struct dirent 结构:
    struct dirent {
        ino_t          d_ino;    // Inode 编号
        off_t          d_off;    // 偏移量
        unsigned short d_reclen; // 记录长度
        unsigned char  d_type;   // 文件类型
        char           d_name[256]; // 文件名(以 '\0' 结尾)
    };
    4.关闭目录:closedir
    int closedir(DIR *dirp);

    功能:关闭目录流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值