当前位置: 首页 > news >正文

Linux文件IO

1.open函数

open()POSIX(Unix/Linux)系统调用,用于打开文件。它返回一个文件描述符(File Descriptor,简称 FD),用于后续读写操作。

 头文件

#include <fcntl.h> // open() 需要 #include <unistd.h> // close() 需要


int open(const char *pathname, int flags);

int open(const char *pathname, int flags, mode_t mode);
参数
  • pathname:要打开的文件路径。
  • flags:文件打开模式(必填)。
  • mode:创建新文件时的权限(仅在 O_CREAT 标志位时需要)。
  • 返回值:成功返回文件描述符(非负整数),失败返回 -1,并设置 errno 以指示错误原因

flags(文件打开模式)

flags 主要分为访问模式附加模式,可使用 |(位或)组合。

(1)基本访问模式(必选一个)

标志含义
O_RDONLY只读打开文件
O_WRONLY只写打开文件
O_RDWR读写打开文件

 mode(文件权限,仅 O_CREAT 时需要)

mode八进制数(0开头) 指定文件权限,如 0644

权限八进制表示说明
rw-r--r--0644所有者可读写,组和其他用户仅可读
rwxr-xr-x0755所有者可读写执行,组和其他用户可读执行
rwx------0700仅所有者可读写执行

2.write() 函数

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);
参数
  • fd:文件描述符,表示已打开的文件。

  • buf:指向要写入数据的缓冲区的指针。

  • count:要写入的字节数。

返回值
  • 成功时:返回实际写入的字节数(通常等于 count)。

  • 失败时:返回 -1,并设置 errno

lseek() 函数

作用
  • 移动文件的读写指针(文件偏移量)。

  • 可以指定参考点(SEEK_SETSEEK_CURSEEK_END)和偏移量。

#include <unistd.h>

off_t lseek(int fd, off_t offset, int whence);
  • fd:文件描述符,表示已打开的文件。

  • offset:偏移量,表示从参考点移动的字节数。

  • whence:参考点,可以是以下值之一:

    • SEEK_SET:从文件开头计算偏移量。

    • SEEK_CUR:从当前文件偏移量计算偏移量。

    • SEEK_END:从文件末尾计算偏移量。

此时,write函数会从当前的文件偏移量开始,向文件中写入数据

3. read() 函数

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);
参数
  • fd:文件描述符,表示已打开的文件。

  • buf:指向存储读取数据的缓冲区的指针。

  • count:要读取的字节数。

返回值
  • 成功时:返回实际读取的字节数(可能小于 count,如果文件末尾已到达)。

  • 失败时:返回 -1,并设置 errno

注意最后最好在buf尾加上"\0"

 ssize_t bytes_read = read(fd, buf, sizeof(buf) - 1);  // 留一个字节给 '\0'
 
 // 添加字符串终止符
 buf[bytes_read] = '\0';

4.dup函数

在 Linux 中,dupdup2 和 dup3 函数用于复制文件描述符,以下是它们的作用和区别:

 

dup

  • 作用:复制一个文件描述符,返回一个新的描述符,指向同一个文件或资源。

  • 特点:新描述符是当前可用描述符中编号最小的。

  • 函数原型

    int dup(int oldfd);
  • 参数

    • oldfd:要复制的文件描述符。

  • 返回值:成功时返回新的文件描述符,失败时返回 -1 并设置 errno

    // 复制文件描述符
    int new_fd = dup(fd);
    if (new_fd == -1) {
        perror("dup");
        return 1;
    }

    printf("Original fd: %d, Duplicated fd: %d\n", fd, new_fd);

运行结果
 

  • 打开文件 test.txt,原始文件描述符为 fd

  • 使用 dup 复制 fd,得到新的文件描述符 new_fd

  • 向 fd 和 new_fd 写入数据,数据都会写入同一个文件 test.txt

dup2


dup2 会复制文件描述符,并指定新的文件描述符编号。如果目标文件描述符已打开,则会先关闭它。
 

 int fd = open("test.txt", O_WRONLY | O_CREAT, 0644);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    // 将标准输出(文件描述符 1)重定向到文件
    if (dup2(fd, STDOUT_FILENO) == -1) {
        perror("dup2");
        return 1;
    }

    // 现在 printf 会写入文件,而不是终端
    printf("This is written to the file via dup2!\n");

运行结果
 

  • 打开文件 test.txt,文件描述符为 fd

  • 使用 dup2 将标准输出(文件描述符 1)重定向到 fd

  • 调用 printf 时,输出会写入文件 test.txt,而不是终端。

dup3


dup3 是 dup2 的扩展版本,支持设置额外的标志(如 O_CLOEXEC)。

int fd = open("test.txt", O_WRONLY | O_CREAT, 0644);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    // 使用 dup3 复制文件描述符,并设置 O_CLOEXEC 标志
    int new_fd = dup3(fd, 10, O_CLOEXEC);
    if (new_fd == -1) {
        perror("dup3");
        return 1;
    }

    printf("Original fd: %d, Duplicated fd: %d\n", fd, new_fd);

    // 写入数据
    write(fd, "Hello from fd\n", 14);
    write(new_fd, "Hello from new_fd\n", 18);


 

  • 打开文件 test.txt,文件描述符为 fd

  • 使用 dup3 复制 fd,并指定新的文件描述符为 10,同时设置 O_CLOEXEC 标志。

  • 向 fd 和 new_fd 写入数据,数据都会写入同一个文件 test.txt

    总结:

如果你只是想复制一个文件描述符,使用 dup

如果你需要重定向文件描述符(如将标准输出重定向到文件),使用 dup2

如果你需要在dup2基础上实现更精细的控制(如设置 O_CLOEXEC 标志),使用 dup3

相关文章:

  • 浅谈canal实例 在docker里面安装canal镜像 Canal监听MySQL数据库变更并同步更新Redis和Elasticsearch 示例
  • zabbix原生linux命令部署和docker部署
  • docker安装milvus向量数据库Attu可视化界面
  • 母婴电商企业案例:日事清驱动项目管理执行与OKR目标管理的流程自动化实践
  • 为什么labelme框选图片后闪退
  • 红宝书第七讲:this绑定与强制类型转换详解(小白指南)
  • 51单片机程序变量作用域问题
  • 【Oracle资源损坏类故障】:详细了解坏块
  • PyTorch分布式训练中各节点如何通信
  • Redis 持久化机制
  • 汇编代码中嵌入回调函数的优化说明
  • Centos7快速在线安装MySQL8.0最新版本教程
  • MySQL WHERE 子句详解
  • 蓝桥杯嵌入式赛道复习笔记5(捕获信号发生器的PWM的波形)
  • word报告篇:python生成《蔬菜店销售数据分析报告》案例
  • Spring Boot整合Apache BookKeeper教程
  • 网络安全之前端学习(HTML篇)
  • Leetcode322-零钱兑换
  • 如何在 WordPress 中重新生成永久链接?
  • HarmonyOS next性能优化:多维度策略与实战案例
  • 出国留学、来华留学呈现双增新趋势,“00后留学生个性鲜明”
  • “五一”假期云南铁路预计发送旅客超330万人次
  • 看展览|深濑昌久:一位超现实主义摄影者的三种意象
  • 东阿至聊城公交票价取消八折优惠:运行成本高昂
  • “全国十大考古”揭晓:盘龙城遗址、周原遗址等入选
  • 云南蒙自:一汪南湖见证近代开埠史与西南联大的弦歌不绝