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

Linux软件编程(三)文件操作-文件 I/O

一、文件 I/O 基础

文件 I/O 是 Linux 内核 提供给应用层的一套文件操作方法,直接通过系统调用实现,移植性相对较弱,但能精确控制文件和硬件的读写。

基本流程

  1. 打开文件 — open

  2. 读/写文件 — read / write

  3. 关闭文件 — close


二、open 函数

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

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

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

功能:打开文件并获得文件描述符(fd)
参数

  • pathname:文件路径

  • flags:打开方式

    • O_RDONLY:只读

    • O_WRONLY:只写

    • O_RDWR:可读可写

    • O_CREAT:创建文件

    • O_TRUNC:清空文件

    • O_APPEND:追加写

  • mode:文件权限(仅在 O_CREAT 时有效)

    • 例如 0664 表示 rw-rw-r--

    • 实际权限 = mode & ~umask

返回值

  • 成功:文件描述符(非负整数)

  • 失败:-1


三、文件描述符

  • 是内核为已打开文件分配的标识符,类型为小的非负整数

  • 范围:0 ~ 1023(Linux 默认支持 1024 个打开文件)

  • 分配原则:最小未使用优先

  • 0、1、2 已被占用:

    • 0 → 标准输入(stdin)

    • 1 → 标准输出(stdout)

    • 2 → 标准错误(stderr)

标准 I/O 与文件 I/O 对比

标准 I/O文件 I/O
FILE *int fd
缓冲区无缓冲区


四、close 函数

#include <unistd.h>

int close(int fd);

功能:关闭文件,释放文件描述符
返回值

  • 成功:0

  • 失败:-1


五、write 函数

ssize_t write(int fd, const void *buf, size_t count);

功能:向文件写入 count 字节数据
参数

  • fd:文件描述符

  • buf:数据首地址

  • count:写入字节数


六、read 函数

ssize_t read(int fd, void *buf, size_t count);

功能:从文件读取 count 字节数据
返回值

  • 成功:实际读取字节数

  • 读到文件末尾:0

  • 失败:-1


七、lseek 函数(文件定位)

#include <unistd.h>

off_t lseek(int fd, off_t offset, int whence);

功能:调整文件读写位置
参数

  • fd:文件描述符

  • offset:偏移量(字节)

  • whence

    • SEEK_SET:文件开头

    • SEEK_CUR:当前位置

    • SEEK_END:文件末尾

示例:获取文件大小

off_t len = lseek(fd, 0, SEEK_END);

lseek(fd, 0, SEEK_SET); // 复位


八、标准 I/O 与文件 I/O 对比

标准 I/O

  1. 属于 C 库函数,跨平台

  2. 封装了系统调用,带缓冲区(效率高)

  3. 常用于普通文件操作

文件 I/O

  1. 属于系统调用,仅适用于 Linux

  2. 无缓冲区

  3. 常用于硬件或特殊文件


九、缓冲区类型

  1. 行缓冲(1KB)

    • 常用于交互式终端

    • 刷新条件:'\n'、缓冲区满、fflush()、程序结束

  2. 全缓冲(4KB)

    • 常用于文件

    • 刷新条件:缓冲区满、fflush()、文件关闭、程序结束

  3. 无缓冲(0KB)

    • 常用于 stderr

十、练习题

  1. 用文件 I/O 实现 cat 功能:

    ./a.out filename

该代码是一个简单的C语言程序,用于读取指定文件内容并输出到标准输出(屏幕)。程序通过命令行参数接收文件路径,以只读方式打开文件并逐块读取内容。

代码分析

#include "head.h"
#include <unistd.h>int main(int argc, char const *argv[])
{if(argc != 2){printf("usager : <a.out> <des>\n");return -1;}int fd = open(argv[1], O_RDONLY);if(fd < 0){printf("open errrr\n");return -1;}char buff[1024] = {0};while(1){ssize_t ret = read(fd, buff, sizeof(buff));if(ret == 0){break;}write(1, buff,ret);}puts("");close(fd);return 0;
}

用文件 I/O 实现文件拷贝:

  1. ./a.out srcfile dstfile

#include "head.h"int main(int argc, char const *argv[])
{if(argc != 3){printf("usager : <a.out> <src> <des>\n");return -1;}int fdsrc = open(argv[1], O_RDONLY);int fddes = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0664);if(fdsrc < 0 || fddes < 0){printf("open error\n");return -1;}char buff[1024] = {0};while(1){ssize_t ret = read(fdsrc, buff, sizeof(buff));if(ret == 0){break;}write(fddes, buff, ret);}close(fddes);close(fdsrc);return 0;
}

http://www.lryc.cn/news/618699.html

相关文章:

  • Outstanding和Credit的概念详解
  • 动态路由协议(一)
  • 《Redis日志系统操作:LIST结构实现日志收集与查询》
  • 在线免VIP的动漫网站
  • 机器学习-集成学习(EnsembleLearning)
  • GitHub的简单使用方法----(4)
  • 为什么灰度图用G(绿色)通道?
  • CSRF 攻击
  • 记对外国某服务器的内网渗透
  • 解释 Spring MVC 的工作原理
  • Linux中使用计划任务和tar命令实现文件备份
  • 模拟人脑处理文本——从段落到时间线叙事,再到动画
  • 【PCB设计经验】去耦电容如何布局?
  • C++ 学习与 CLion 使用:(二)using namespace std 语句详解,以及 std 空间的标识符罗列
  • 【python实用小脚本-182】Python一键爬取今日新闻:5分钟生成Word+CSV——再也不用复制粘贴
  • 【web站点安全开发】任务2:HTML5核心特性与元素详解
  • 02-Ansible 基本使用
  • Python day42
  • 【运维进阶】Ansible 自动化
  • [激光原理与应用-250]:理论 - 几何光学 - 透镜成像的优缺点,以及如克服缺点
  • TensorBoard的使用 小土堆pytorch记录
  • centos 怎么部署 vscode 网页版
  • 半精度模型(16位)解析
  • TRO风暴预警GoPro携BSF律所重拳打击跨境侵权
  • QT6 如何在Linux Wayland 桌面系统抓屏和分享屏幕
  • 使用Excel制作甘特图
  • 将黑客拒之物联网网络之外的竞赛
  • 5G毫米波现状概述(截止2025 年7月)
  • ROS教育中自动驾驶机器人的技术融合与技术创新
  • 门店销售机器人的认知革命:当传统机械邂逅Deepoc具身智能