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

《嵌入式Linux应用编程(四):Linux文件IO系统调用深度解析》

今日学习内容

1. 文件IO与标准IO核心对比

特性标准IO文件IO
实现层C标准库Linux内核系统调用
缓冲机制全缓冲/行缓冲无缓冲(实时读写)
操作对象FILE*流指针整型文件描述符(fd)
移植性跨平台兼容Linux特有
典型应用场景普通文件操作硬件设备/特殊文件操作
性能特点减少系统调用(批量操作高效)实时响应(适合高频小数据)

2. 文件描述符(File Descriptor)

(1) 内核级文件访问句柄

  • 本质:整数标识符(索引内核文件表)
  • 预定义fd
    fd符号设备
    0STDIN标准输入
    1STDOUT标准输出
    2STDERR标准错误

(2) 生命周期管理

int fd = open("file.txt", O_RDWR);  // 获取fd  
read(fd, buf, size);                // 使用fd操作  
close(fd);                         // 释放fd(必须!)  

 

3. 文件权限控制:umask机制

(1) 权限计算规则

权限计算遵循公式:mode & ~umask

  • 查看umask:终端输入umask

4. 核心系统调用详解

(1) 文件打开:open

#include <fcntl.h>  
#include <sys/types.h>
#include <sys/stat.h>
int open(const char *pathname, int flags, mode_t mode);  

 

参数说明
pathname文件路径
flags打开标志
mode创建文件时的权限(仅O_CREAT时有效)

常用flags组合

场景flags组合
只读打开O_RDONLY
只写打开O_WRONLY
读写打开O_RDWR
创建文件O_CREAT
追加写入O_APPEND
清空文件O_TRUNC

(2) 数据读取:read

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);  

 

  • 返回值
    • 成功:实际读取字节数
    • 文件末尾:0
    • 错误:-1

(3) 数据写入:write

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);  

 

  • 返回值:实际写入字节数(可能小于请求值)

(4) 文件定位:lseek

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);  

 

whence定位基准
SEEK_SET文件开头
SEEK_CUR当前位置
SEEK_END文件末尾

典型应用

lseek(fd, 0, SEEK_END);  // 定位到文件末尾  

 

(5) 文件关闭:close

 #include <unistd.h>int close(int fd);  // 成功返回0,失败返回-1  

打开的文件描述符必须显式关闭!

5. 代码

open.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc, char const *argv[])
{int fd = open("./2.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664);if(-1 == fd){printf("error\n");return -1;}printf("fd = %d\n", fd);close(fd);return 0;
}

​​​​write.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc, char const *argv[])
{int fd = open("./2.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664);if(-1 == fd){printf("error\n");return -1;}char *buf = "hello";write(1, buf, sizeof(buf));close(fd);return 0;
}

read.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc, char const *argv[])
{int fd = open("./2.txt", O_RDONLY);if(-1 == fd){printf("error\n");return -1;}char buff[1024] = {0};ssize_t cnt = read(fd, buff, sizeof(buff));// printf("cnt = %ld\n", cnt);printf("buff = %s\n", buff);close(fd);return 0;
}

cats

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc, char const *argv[])
{int fd = open(argv[1], O_RDONLY);if(-1 == fd){printf("error\n");return -1;}char buff[1024] = {0};while(1){ssize_t cnt = read(fd, buff, sizeof(buff));write(1, buff, cnt);if(0 == cnt){break;}}close(fd);return 0;
}

copy.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc, char const *argv[])
{int fd = open(argv[1], O_RDONLY);if(-1 == fd){printf("error\n");return -1;}char buff[1024] = {0};while(1){ssize_t cnt = read(fd, buff, sizeof(buff));write(1, buff, cnt);if(0 == cnt){break;}}close(fd);return 0;
}

lseek.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc, char const *argv[])
{int fd = open("./1.txt", O_RDONLY);if(fd < 0){printf("error\n");return -1;}off_t len = lseek(fd, 0, SEEK_END);printf("%ld\n", len);lseek(fd, 0, SEEK_SET);close(fd);return 0;
}

rizhi.c

#include <stdio.h>
#include <time.h>
#include <unistd.h>
FILE *fp = NULL;
int init_log()
{fp = fopen("./log.txt", "a");if(NULL == fp){printf("open error\n");return -1;}  return 0;
}int write_log(int level)
{time_t now = time(NULL);struct tm *pt = localtime(&now);const char *plevel = {0};switch (level) {case 2:  plevel = "ERROR";   break;case 1:  plevel = "WARNING"; break;case 0:  plevel = "INFO";    break;}fprintf(fp, "[%d-%d-%d %d:%d:%d] [%d]:%s\n", pt->tm_year+1900, pt->tm_mon+1,pt->tm_mday,pt->tm_hour, pt->tm_min, pt->tm_sec, level, plevel);return 0;
}void unint_log()
{fclose(fp);
}int main(void)
{init_log();int i;for(i = 0; i < 100; ++i){write_log(2);  write_log(0);write_log(1); }unint_log();return 0;
}

 

 


总结

  1. 文件IO核心价值
    • 直接内核交互 → 实时性保障
    • 设备文件操作唯一途径
  2. 系统调用
    操作关键注意
    open正确处理O_CREAT的mode参数
    read/write循环处理部分写入/读取
    lseek支持负偏移(向前回溯)
    close配对调用防止fd泄漏
  3. 嵌入式场景适配
    • 设备驱动开发必用文件IO
    • 日志系统优先选无缓冲写入(防断电丢失)
    • 敏感文件设置严格权限(open(..., 0600)

 

http://www.xdnf.cn/news/1288171.html

相关文章:

  • GraphQL 原理、应用与实践指南
  • 【Altium designer】快速建立原理图工程的步骤
  • Day05 店铺营业状态设置 Redis
  • MySQL-多表查询
  • 第23章,景深:技术综述
  • 下一代防火墙技术
  • 【KO】android 面试 算法
  • 数字气压传感器,筑牢汽车TPMS胎压监测系统的精准感知基石
  • 西门子S7-200与S7-1200通过PPI以太网模块通讯,赋能汽车制造行业发展
  • 如何在 Ubuntu 24.04 LTS Linux 中安装 JSON Server
  • WebAssembly的原理与使用
  • 前端最新Vue2+Vue3基础入门到实战项目全套教程,自学前端vue就选黑马程序员,一套全通关!笔记
  • Tauri Qt孰优孰劣
  • 计算机毕设不知道选什么题目?基于Spark的糖尿病数据分析系统【Hadoop+Spark+python】
  • 数据结构 二叉树(2)堆
  • 91、23种经典设计模式
  • AI大模型基础:BERT、GPT、Vision Transformer(ViT)的原理、实现与应用
  • 农业智慧大屏系统 - Flask + Vue实现
  • 飞算AI:企业智能化转型的新引擎
  • 嵌入式硬件——ARM
  • 【虚拟机】VMwareWorkstation17Pro安装步骤
  • 三维工厂设计软件 AutoCAD Plant 3D 安装图文教程
  • Nginx 启用 HTTPS:阿里云免费 SSL 证书详细图文教程(新手0.5小时可完成)
  • C# 基于halcon的视觉工作流-章29-边缘提取-亚像素
  • AI Agent——基于 LangGraph 的多智能体任务路由与执行系统实战
  • 蓝桥杯电子赛----嵌入式赛道备赛LED
  • lesson36:MySQL从入门到精通:全面掌握数据库操作与核心原理
  • Python初学者笔记第二十四期 -- (面向对象编程)
  • 计算机网络1-7:第一章 概述 章节小结
  • 用 Apache Iceberg 与 Apache Spark 在 Google Cloud 打造高性能、可扩展的数据湖仓