恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

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

  • 首页
  • 资讯中心
  • /
  • 【linux应用软件编程】文件操作学习3【目录IO、出错处理及framebuffer基础操作】

相关资讯

QZoneExport 使用教程:三步把QQ空间数据完整备份到本地 2026/8/25 19:35:24
艾默生 TREX2‑CHPNAWS1S 手操器使用说明|新机到货验收 实操注意事项 2026/8/25 19:30:24
Nucleus Co-Op 免费分屏多开工具:从克隆到四人同屏的完整上手指南 2026/8/25 19:30:24

最新资讯

基于SpringBoot的社区团购小程序的设计与实现源码+文档+讲解视频
**央视纪录片教学素材指南:中小学老师怎么建自己的免费素材库
基于java+springboot的教务管理系统设计与实现(源码+lw+部署文档+讲解等)
免费把 NCM 转 MP3:ncmdump 三步拖拽上手教程
Matplotlib子图编程:深入理解figure与axes对象
生态学硕士论文降AI工具免费推荐:2026年生态专业研究生论文降AI4.8元亲测达标方案

今日推荐

三步把QQ空间历史说说导出到本地:GetQzonehistory 极简指南
洛谷 P7912:[CSP-J 2021 T4] 小熊的果篮 ← 双向链表
Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG

本周热门

Nextcloud 桌面客户端:把同步交给它,你只管改文件
如何将 HTML 转成 Word 文档且格式不丢失?html-to-docx 使用教程
Anki 批量操作卡片完整指南:一次搞定上千张,不再逐张修改

本月精选

如何用DamaiHelper实现演唱会门票的智能自动化抢购:完整技术解决方案指南
第4篇:59 倍性能差距的索引瓶颈定位——一次教科书级的全表扫描调优
终极歌词批量下载神器:5分钟解决离线音乐库歌词同步难题

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

发布时间:2026/8/25 19:35:24
【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格式图片的方法。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号