【linux应用软件编程】文件操作学习3【目录IO、出错处理及framebuffer基础操作】

发布时间:2026/8/25 19:35:34

【linux应用软件编程】文件操作学习3【目录IO、出错处理及framebuffer基础操作】
文章目录前言一、目录IO1.1 打开目录文件opendir()1.2 读取目录文件readdir()1.3 关闭目录文件closedir()1.4 文件夹创建mkdir()1.5 使用示例目录遍历二、出错处理2.1 strerror2.2 perror三、framebuffer3.1 什么是framebuffer3.2 如何操作framebuffer3.2.1 打开显示设备文件3.2.2 获取显示设备的相关参数3.2.3 建立内存映射3.2.4 写入RGB颜色值3.2.5 解除内存映射与关闭显示设备文件前言上篇文章我们学习了文件相关基础知识及标准IO和文件IO这篇文章我们主要是对文件IO的一个补充即目录IO的学习还有对出错处理的一个学习以及对之前C语言五子棋项目实战中framebuffer帧缓存技术的补充学习。下面是之前相关知识的博客文章感兴趣的可以看一看文件相关基础知识及【标准IO】文件IO及文件IO与标准IO的区别基于【C语言】和【framebuffer】的五子棋游戏项目一、目录IO打开目录文件opendir()读取目录文件readdir()关闭目录文件closedir()1.1 打开目录文件opendir()函数原型#includesys/types.h#includedirent.hDIR*opendir(constchar*name);功能打开目录文件并获得目录流指针。参数name目录文件名。返回值成功返回目录流指针失败返回NULL。1.2 读取目录文件readdir()函数原型#includedirent.hstructdirent*readdir(DIR*dirp);功能从目录流中读取数据。参数dirp目录流指针。返回值成功文件末尾NULL失败NULL。1.3 关闭目录文件closedir()函数原型#includesys/types.h#includedirent.hintclosedir(DIR*dirp);功能关闭目录文件。参数dirp目录流指针。返回值成功返回0失败返回-1.1.4 文件夹创建mkdir()函数原型#includesys/stat.h#includesys/types.hintmkdir(constchar*pathname,mode_tmode);功能创建一个文件夹。参数pathname创建的文件夹的名称mode权限设置。返回值成功返回0失败返回-1。1.5 使用示例目录遍历通过调用opendir打开上级目录通过readdir循环读取目录项信息打印每个文件的文件名、inode 编号依据dirent结构体中的d_type字段识别并输出文件类型最后调用closedir关闭目录完成目录遍历。#includestdio.h#includedirent.hvoidget_type(structdirent*pinfo){switch(pinfo-d_type){caseDT_BLK:printf(%s : b\n,pinfo-d_name);break;caseDT_CHR:printf(%s : c\n,pinfo-d_name);break;caseDT_DIR:printf(%s : d\n,pinfo-d_name);break;caseDT_FIFO:printf(%s : p\n,pinfo-d_name);break;caseDT_LNK:printf(%s : l\n,pinfo-d_name);break;caseDT_REG:printf(%s : -\n,pinfo-d_name);break;caseDT_SOCK:printf(%s : s\n,pinfo-d_name);break;default:printf(%s : unknow\n,pinfo-d_name);break;}}intmain(){DIR*pdiropendir(..);if(NULLpdir){printf(opendir error!\n);return-1;}while(1){structdirent*pinforeaddir(pdir);if(NULLpinfo){break;}printf(%s : %ld\n,pinfo-d_name,pinfo-d_ino);get_type(pinfo);}closedir(pdir);return0;}二、出错处理2.1 strerror函数原型#includestring.hchar*strerror(interrnum);功能将错误码转化为对应的错误信息字符串。参数errnum错误码errno。返回值成功返回对应错误信息字符串的首地址失败返回NULL。注意使用errno需要包含errno.h这个头文件。2.2 perror函数原型#includestdio.hvoidperror(constchar*s);功能打印自己的出错信息和系统给出的出错原因。参数自己的出错信息字符串。返回值无返回值。三、framebuffer3.1 什么是framebuffer帧缓存、帧缓冲技术是Linux为显示设备提供的一个接口把显存抽象后的一种设备文件通过该设备文件可以实现应用层向显存空间的数据写入从而实现像素点的绘制。3.2 如何操作framebuffer通过内存映射技术可以实现显存空间和用户空间的内存映射通过向用户空间写入RGB颜色值从而实现显存数据的写入。像素点位数/位深度的种类RGB888 四个字节RGB565 两个字节framebuffer的操作流程打开显示设备文件/dev/fb0获取显示设备的相关参数分辨率、像素点位数/位深度建立内存映射写入RGB颜色值解除内存映射关闭显示设备文件。3.2.1 打开显示设备文件通过我们的文件IO的函数接口open()打开framebuffer的设备文件它在/dev/fb0这个目录下//1. 打开fbopen(/dev/fb0,O_RDWR);if(-1fb){perror(open /dev/fb0 error);return-1;}3.2.2 获取显示设备的相关参数我们通过ioctl()这个系统调用的函数接口来获取设备的相关参数它的描述是这样的ioctl()系统调用用于操控特殊文件底层对应的设备参数。参数fd必须是一个已经成功打开的文件描述符。第二个参数是依赖具体设备的请求命令码request。不同驱动命令码含义完全不一样没有全局统一标准。第三个参数是一个无类型的内存指针。历史上C 语言还没有void*时这里约定使用char *argp所以手册后续讲解中将它命名为argp。也就是原型里的可变参数你可以传任意类型指针。在linuxubuntu:/usr/include/linux$这个路径下的的fb.h文件是Linux 液晶屏帧缓冲驱动专用头文件里面定义了 Framebuffer 设备 (/dev/fb0) 所有可用的ioctl命令码。例如FBIOGET_VSCREENINFO这个宏就是我们现在需要的获取虚拟屏幕可变信息的命令码分辨率、色深、像素格式等。还有这个struct fb_var_screeninfo 可变屏幕信息结构体structfb_var_screeninfo{__u32 xres;/* visible resolution */__u32 yres;__u32 xres_virtual;/* virtual resolution */__u32 yres_virtual;__u32 xoffset;/* offset from virtual to visible */__u32 yoffset;/* resolution */__u32 bits_per_pixel;/* guess what */__u32 grayscale;/* 0 color, 1 grayscale, *//* 1 FOURCC */structfb_bitfieldred;/* bitfield in fb mem if true color, */structfb_bitfieldgreen;/* else only length is significant */structfb_bitfieldblue;structfb_bitfieldtransp;/* transparency */__u32 nonstd;/* ! 0 Non standard pixel format */__u32 activate;/* see FB_ACTIVATE_* */__u32 height;/* height of picture in mm */__u32 width;/* width of picture in mm */__u32 accel_flags;/* (OBSOLETE) see fb_info.flags */};成员变量含义说明xres/yres可见屏幕分辨率实际 LCD 显示宽高像素例800×480xres800yres480xres_virtual/yres_virtual虚拟显存分辨率显存可以开辟一块比屏幕更大的画布用于硬件滚屏、双缓冲。例如虚拟高度设为yres*2实现页面翻页xoffset/yoffset显示偏移量从虚拟显存的(xoffset,yoffset)位置开始截取画面输出到屏幕修改yoffset配合大的yres_virtual即可实现硬件滚动 (Panning)bits_per_pixel每个像素占用比特数色深常见值16 (RGB565)、24 (RGB888)、32 (RGBA8888)grayscale灰度模式标志0 彩色1 灰度大于 1 代表使用 FOURCC 压缩图像格式red/green/blue/transpRGB 分量位域信息struct fb_bitfield结构体包含每个颜色通道起始偏移位、占用位数。RGB565红占 5bit绿占 6bit蓝占 5bitnonstd非标准像素格式标记非 0 代表不是标准 RGB 格式activate参数生效时机。控制调用FBIOPUT_VSCREENINFO后新分辨率是立刻生效还是等到下一次 vsync 垂直同步height/width屏幕物理尺寸单位毫米 (mm)用于计算 DPI不影响像素绘图accel_flags硬件加速标志已经废弃不再使用代码示例//2. 获取显示设备的相关参数structfb_var_screeninfovinfo;intretioctl(fb,FBIOGET_VSCREENINFO,vinfo);if(-1ret){perror(ioctl error);return-1;}printf(vinfo.xres %d, vinfo.yres %d\n,vinfo.xres,vinfo.yres);printf(vinfo.xres_virtual %d, vinfo.yres_virtual %d\n,vinfo.xres_virtual,vinfo.yres_virtual);printf(vinfo.bits_per_pixel %d\n,vinfo.bits_per_pixel);3.2.3 建立内存映射以这两张图为例Linux帧缓冲通过mmap将位于内核空间的物理显存映射到用户进程虚拟地址空间程序获得映射指针pmem后便可利用公式*(pmem y*w x)直接计算像素偏移通过指针赋值直接修改显存数据无需调用read/write显存更新后硬件自动刷新到800×600的显示屏上实现屏幕绘图。显存可开辟一块大于实际屏幕xres × yres的虚拟画布xres_virtual × yres_virtual屏幕仅截取画布的一部分画面进行显示修改x_offset、y_offset显示偏移量无需移动显存像素数据就能快速切换可视区域从而实现硬件滚屏、双缓冲翻页效果。mmap()函数原型#includesys/mman.hvoid*mmap(void*addr,size_tlength,intprot,intflags,intfd,off_toffset);功能建立文件和用户空间的内存映射。参数addr要映射的用户空间的首地址一般情况下填NULL让内核自己寻找一块连续的内存空间并将空间首地址返回length要映射的用户空间大小prot对映射空间的读写权限1. PROT_READ2. PROT_WRITEflagsMAP_SHARED共享映射区域fd要映射的文件描述符offset映射的偏移量返回值成功返回映射到的用户空间首地址失败返回MAP_FAILED((void *)-1)。内存映射代码示例void*pmemNULL;//3. 建立内存映射lenvinfo.xres_virtual*vinfo.yres_virtual*vinfo.bits_per_pixel/8;pmemmmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);if(MAP_FAILEDpmem){perror(mmap error);return-1;}3.2.4 写入RGB颜色值首先校验像素坐标是否超出可视屏幕范围随后基于虚拟显存宽度计算目标像素的内存偏移通过显存映射指针pmem直接向帧缓冲写入指定颜色值完成单点绘制。voidshow_point(intx,inty,unsignedintcol){//4. 写入RGB颜色值if(xvinfo.xres||yvinfo.yres){return;}*((unsignedint*)pmemy*vinfo.xres_virtualx)col;}3.2.5 解除内存映射与关闭显示设备文件munmap()函数原型#includesys/mman.hintmunmap(void*addr,size_tlength);功能解除mmap()建立的内存映射释放用户空间与物理显存之间的映射关系取消后不能再通过该指针访问显存关闭帧缓冲文件前必须调用。参数addrmmap返回的映射起始虚拟地址如前面的pmemlength需要解除映射的内存字节长度显存映射大小finfo.smem_len返回值成功返回0失败返回-1并设置errno错误号代码示例voiddeinit_fb(){//5. 解除内存映射munmap(pmem,len);//6. 关闭显示设备文件。close(fb);}通过这些步骤我们就可以绘制一个点了再借助这个点绘制的函数接口我们就可以进一步封装其他绘制函数了等下一篇文章我将进一步分享通过framebuffer绘制bmp格式图片的方法。

相关新闻

QZoneExport 使用教程:三步把QQ空间数据完整备份到本地

QZoneExport 使用教程:三步把QQ空间数据完整备份到本地

2026/8/25 19:35:34

QZoneExport 使用教程:三步把QQ空间数据完整备份到本地 【免费下载链接】QZoneExport QQ空间导出助手,用于备份QQ空间的说说、日志、私密日记、相册、视频、留言板、QQ好友、收藏夹、分享、最近访客为文件,便于迁移与保存 项目地址: https:…

LangChain Agent与MCP实战:构建能调用工具的大模型应用

LangChain Agent与MCP实战:构建能调用工具的大模型应用

2026/8/25 19:25:33

1. 先搞清楚 LangChain Agent、MCP 和 Skills 到底能帮你解决什么如果你正在用 Claude、GPT 这类大模型,但总觉得它们像个“万事通,万事松”——什么都知道一点,但一到具体操作,比如查数据库、调 API、操作本地文件,就…

技术面试150题训练体系:第四周综合题型突破

技术面试150题训练体系:第四周综合题型突破

2026/8/25 19:25:33

1. 项目概述"面试150"这个标题乍看简单,实则暗藏玄机。作为经历过上百场技术面试的老兵,我深知这个数字背后的分量——它代表着系统化、高强度、持续性的面试训练体系。第四周意味着已经完成了前三周的积累,进入了一个关键的提升阶…

AI时代软件基本功:从代码整洁到人机协作的工程实践

AI时代软件基本功:从代码整洁到人机协作的工程实践

2026/8/25 20:25:36

在 AI 工具日益普及的今天,一个尖锐的问题摆在了每一位开发者面前:当 AI 能够生成代码、重构函数甚至编写测试时,我们过去所强调的命名规范、函数拆分、设计模式等“软件基本功”是否已经过时?Matt Pocock 与《代码整洁之道》作者…

上海全屋定制避坑要点

上海全屋定制避坑要点

2026/8/25 20:25:36

随着改善型居住需求的释放,上海全屋定制市场的服务成熟度不断提升,但由于产业链条长、涉及环节多,消费者踩坑的情况仍时有发生。行业抽样调研显示,近3年上海全屋定制相关消费投诉中,增项收费、品质缩水、履约滞后三类问…

Codex中文界面永久设置指南:配置文件与环境变量详解

Codex中文界面永久设置指南:配置文件与环境变量详解

2026/8/25 20:25:36

如果你正在找 Codex 中文界面的设置方法,并且希望设置一次就永久生效,那这篇文章就是为你准备的。Codex 本身是一个强大的代码辅助工具,但它的界面默认是英文的,这让很多习惯中文环境的开发者感到不便。网上流传的方法很多&#x…

智能报价单解析与风控:QClaw项目实战,构建供应链合规自动化防线

智能报价单解析与风控:QClaw项目实战,构建供应链合规自动化防线

2026/8/25 20:25:36

1. 项目概述:当报价单遇上合规,一场数据与风险的博弈在供应链这个庞大而精密的系统中,每一份报价单都不仅仅是价格的载体,它更像是一份浓缩了商业意图、成本构成、合规承诺与潜在风险的“数据契约”。我们团队最近刚完成一个代号为…

三步接入腾讯云图片内容安全,为应用快速构建审核防线

三步接入腾讯云图片内容安全,为应用快速构建审核防线

2026/8/25 20:25:36

1. 项目概述:为什么内容安全是“一把手工程”?最近和几个做社区、电商、社交产品的朋友聊天,大家不约而同地提到了同一个痛点:内容安全。一个朋友的公司,因为用户上传的一张违规图片没被及时拦截,导致应用商…

OpenClaw消息工具:统一消息中枢的设计原理与实战应用

OpenClaw消息工具:统一消息中枢的设计原理与实战应用

2026/8/25 20:15:35

1. 项目概述:为什么我们需要一个统一的消息中枢?最近在折腾一个内部自动化项目,需要把不同来源的告警、通知和任务状态推送到不同的地方,比如钉钉群、企业微信、飞书,甚至短信和邮件。一开始图省事,每个服务…

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

2026/8/24 19:53:32

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

2026/8/24 19:56:07

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

2026/8/24 21:16:09

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

三步把QQ空间历史说说导出到本地:GetQzonehistory 极简指南

三步把QQ空间历史说说导出到本地:GetQzonehistory 极简指南

2026/8/25 0:04:34

三步把QQ空间历史说说导出到本地:GetQzonehistory 极简指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory Meta Description:GetQzonehistory 是一个QQ空间历史说…

洛谷 P7912:[CSP-J 2021 T4] 小熊的果篮 ← 双向链表

洛谷 P7912:[CSP-J 2021 T4] 小熊的果篮 ← 双向链表

2026/8/25 0:04:35

【题目来源】 https://www.luogu.com.cn/problem/P7912 【题目描述】 小熊的水果店里摆放着一排 n 个水果。每个水果只可能是苹果或桔子,从左到右依次用正整数 1,2,…,n 编号。连续排在一起的同一种水果称为一个“块”。小熊要把这一排水果挑到若干个果篮里&#x…

Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG

Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG

2026/8/25 0:04:35

Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG 【免费下载链接】transformers.js State-of-the-art Machine Learning for the web. Run 🤗 Transformers directly in your browser, with no need for a server! 项目地址: https:/…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/22 2:02:26

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/22 4:13:47

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/22 1:32:34

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…