这篇接着之前的文件IO往下记,主要是目录操作、一些常用辅助函数,还有framebuffer的基本用法。
一、目录IO
目录也是文件,操作思路跟普通文件一样:打开、读、关闭。
- 打开和关闭目录
DIR *opendir(const char *name);
打开一个目录,成功返回目录流指针,失败返回NULL。
int closedir(DIR *dirp);
关闭目录,成功返回0,失败-1。
- 读取目录内容
struct dirent *readdir(DIR *dirp);
从目录流里读一条文件信息,成功返回struct dirent指针,读到末尾或失败返回NULL。
这个结构体里重点关注两个字段:
struct dirent {
ino_t d_ino; // inode号
char d_name256; // 文件名
};
- 创建目录
int mkdir(const char *pathname, mode_t mode);
创建一个目录文件,参数是目录名和权限,成功0失败-1。
- 遍历目录的例子
下面这段代码遍历/dev目录,打印每个文件的名字和inode号,跳过以点开头的隐藏文件:
int main(void)
{
DIR *pdir = opendir("/dev");
if (NULL == pdir)
{
printf("opendir error\n");
return -1;
}
while (1)
{
struct dirent *pinfo = readdir(pdir);
if (NULL == pinfo)
{
break;
}
if ('.' == pinfo->d_name0)
{
continue;
}
printf(" %s : %ld\n", pinfo->d_name, pinfo->d_ino);
}
closedir(pdir);
return 0;
}
二、其他常用函数
- 格式化输出系列
除了最常用的printf,还有几个变体:
int fprintf(FILE *stream, const char *format, ...);
把格式化字符串写入指定的文件流。
int dprintf(int fd, const char *format, ...);
跟fprintf类似,只不过参数是文件描述符而不是文件流指针。
int sprintf(char *str, const char *format, ...);
把格式化结果写到字符数组里,常用于字符串拼接或者把数字转成字符串。
- 字符串截取
char *strtok(char *str, const char *delim);
按指定分隔符截取字符串。第一次调用传原始字符串,后续调用传NULL,会接着上一次的位置继续截。截到末尾返回NULL。
- 出错处理
Linux系统调用失败时会设置全局变量errno,两个常用的错误处理函数:
char *strerror(int errnum);
把错误码转换成对应的错误信息字符串。
void perror(const char *s);
直接打印自定义提示加上系统给出的错误原因,比如 perror("open") 会输出 open: No such file or directory 这种格式。
三、Framebuffer
- 什么是framebuffer
帧缓冲,是Linux给显示设备提供的一个接口。它把显存抽象成设备文件,应用层往这个设备里写数据,就能控制屏幕上每个像素点的颜色。
-
操作步骤
-
打开显示设备文件 /dev/fb0
-
获取显示参数(分辨率、位深度)
-
建立内存映射
-
往映射空间写RGB颜色值
-
解除映射
-
关闭设备文件
核心是mmap函数:
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
建立文件和用户空间的内存映射。几个关键参数:
-
addr :要映射的用户空间首地址,传NULL让内核自动分配
-
length :映射空间大小
-
prot :读写权限,一般用 PROT_READ | PROT_WRITE
-
flags :通常用 MAP_SHARED ,共享映射
-
fd :要映射的文件描述符
-
offset :映射偏移量
成功返回映射到的用户空间首地址,失败返回 MAP_FAILED 。
拿到映射地址之后,直接往里面写RGB值就能在屏幕上画点了,本质上就是操作一块连续的内存。
以上就是目录IO、常用辅助函数和framebuffer的核心内容,都是Linux应用编程里比较基础的部分,记下来方便以后翻。