linux目录编程:DIR,stat, dirent结构体解析与应用
来源:互联网 发布:软件自动升级程序 编辑:程序博客网 时间:2024/05/21 06:28
在Linux中,“一切都是文件”。对文本文件编程我应用的比较多,但是对目录文件的操作涉及的比较少。在对目录编程中,会用到DIR,stat, dirent这些结构体,下面就介绍他们的一些基本信息和应用实例。
DIR 结构
DIR 类似于 FILE ,是一个内部结构体,定义如下:
struct __dirstream { void *__fd; char *__data; int __entry_data; char *__ptr; int __entry_ptr; size_t __allocation; size_t __size; __libc_lock_define (, __lock) }; typedef struct __dirstream DIR;常用的操作函数有:
struct dirent *readdir(DIR *dp); /* 返回参数dp目录流的下个目录进入点*/
void rewinddir(DIR *dp); /* 把目录指针恢复到目录的起始位置 */
int closedir(DIR *dp); /* 关闭参数dp所指的目录流 */
long telldir(DIR *dp);/* 获取当前dp位置 返回目录流dp的当前位置,此返回值代表距离目录文件开头的偏移量,有错误发生时返回-1 */
void seekdir(DIR *dp, long loc); /* 用来设置参数dp目录流当前的读取位置,在调用readdir()时便从此新位置开始读取。参数loc代表距离目录文件开头的偏移量 */
stat 结构
struct stat { dev_t st_dev; //文件的设备编号 ino_t st_ino; //节点 mode_t st_mode; //文件的类型和存取的权限 nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为1 uid_t st_uid; //用户ID gid_t st_gid; //组ID dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号 off_t st_size; //文件字节数(文件大小) unsigned long st_blksize; //块大小(文件系统的I/O 缓冲区大小) unsigned long st_blocks; //块数 time_t st_atime; //最后一次访问时间 time_t st_mtime; //最后一次修改时间 time_t st_ctime; //最后一次改变时间(指属性)};上面结构体中的st_mode 在POSIX中定义了检查这些类型的宏定义:
S_ISLNK (st_mode) 判断是否为符号连接
S_ISREG (st_mode) 是否为一般文件
S_ISDIR (st_mode) 是否为目录
S_ISCHR (st_mode) 是否为字符装置文件
S_ISBLK (st_mode) 是否为块设备
S_ISSOCK(st_mode) 是否为socket
stat函数讲解
表头文件:
#include <sys/stat.h>
#include <unistd.h>
定义函数: int stat(const char *file_name, struct stat *buf);函数说明: 通过文件名filename获取文件信息,并保存在buf所指的结构体stat中
返回值: 执行成功则返回0,失败返回-1,错误代码存于errno
错误代码:
ENOENT 参数file_name指定的文件不存在
ENOTDIR 路径中的目录存在但却非真正的目录
ELOOP 欲打开的文件有过多符号连接问题,上限为16符号连接
EFAULT 参数buf为无效指针,指向无法存在的内存空间
EACCESS 存取文件时被拒绝
ENOMEM 核心内存不足
ENAMETOOLONG 参数file_name的路径名称太长
相关函数:
int stat(const char *restrict pathname, struct stat *restrict buf);
提供文件名字,获取文件对应属性。
int fstat(int filedes, struct stat *buf);通过文件描述符获取文件对应的属性。
int lstat(const char *restrict pathname, struct stat *restrict buf);
连接文件名字,获取文件属性。
stat与lstat的区别:
对于链接文件,stat 获取到的是链接文件指向文件的文件信息, lstat获取到的是连接文件本身的信息。
stat与fstat的区别:
stat 输入的是文件的名字,fstat 输入的是文件描述符。
dirent解析
struct dirent { long d_ino; /* inode number 索引节点号 */ off_t d_off; /* offset to this dirent 在目录文件中的偏移 */ unsigned short d_reclen; /* length of this d_name 文件名长 */ unsigned char d_type; /* the type of d_name 文件类型 */ char d_name [NAME_MAX+1] /* file name (null-terminated) 文件名,最长255字符 */ }
dirent结构体的内容不多,它主要的作用是起到索引的作用。要获取文件的主要信息,需要与stat结合使用。
应用实例:
#include <unistd.h>#include <stdio.h>#include <dirent.h>#include <string.h>#include <sys/stat.h>#include <stdlib.h>/* 递归调用,输出目录下所有目录及文件*/void printdir(char *dir, int depth){DIR *dp;struct dirent *entry;struct stat statbuf;/* 打开目录 */if ((dp = opendir(dir)) == NULL) {fprintf(stderr, "Can`t open directory %s\n", dir);return ;}/* 切换目录 */chdir(dir);/* 返回目录流下个目录的进入点 */while ((entry = readdir(dp)) != NULL) {lstat(entry->d_name, &statbuf);/* 判断是否为目录*/if (S_ISDIR(statbuf.st_mode)) {/* 如果是 . 或.. 目录,结束该次循环 */if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0 ){continue;}/* %*s 这里 * 被depth 代替,做标准输出最小长度控制,输出目录名 */printf("%*s%s/\n", depth, "", entry->d_name);/* 递归调用 */printdir(entry->d_name, depth+4);} else{/* 输出文件名 */printf("%*s%s\n", depth, "", entry->d_name);}}/* 切换到目录 .. */chdir("..");/* 关闭目录 */closedir(dp);}int main(int argc, char *argv[]){ char *topdir = "."; if (argc >= 2){ topdir = argv[1];} printf("Directory scan of %s\n", topdir);printdir(topdir, 0);printf("done.\n");exit(0);}当前目录结构如下:
biao@ubuntu:~/test/file$ lsa.out dir_test.c testbiao@ubuntu:~/test/file$ tree.├── a.out├── dir_test.c└── test ├── test ├── test1 │ ├── test │ └── test2 │ ├── test2 │ └── test3 │ └── test3 ├── test1_1 │ └── test1_1 └── test1_2 └── test1_26 directories, 8 filesbiao@ubuntu:~/test/file$执行结果如下:
biao@ubuntu:~/test/file$ biao@ubuntu:~/test/file$ lsa.out dir_test.c testbiao@ubuntu:~/test/file$ ./a.out Directory scan of .dir_test.ca.outtest/ test1/ test test2/ test3/ test3 test2 test test1_2/ test1_2 test1_1/ test1_1done.biao@ubuntu:~/test/file$
阅读全文
0 0
- linux目录编程:DIR,stat, dirent结构体解析与应用
- Linux下DIR,dirent,stat 结构体
- Linux下DIR,dirent,stat等结构体详解
- Linux下DIR,dirent,stat等结构体详解
- Linux下DIR,dirent,stat等结构体详解
- Linux下DIR,dirent,stat等结构体详解
- Linux下DIR,dirent,stat等结构体详解
- Linux下DIR,dirent,stat等结构体详解
- Linux下DIR,dirent,stat等结构体详解
- Linux下DIR,dirent,stat等结构体详解
- Linux下DIR,dirent,stat等结构体详解
- Linux下DIR,dirent,stat等结构体详解
- Linux下DIR,dirent,stat等结构体详解
- Linux下DIR,dirent,stat等结构体详解
- Linux下DIR,dirent,stat等结构体详解
- Linux下DIR,dirent,stat等结构体详解
- Linux下的DIR,dirent,stat等结构体详解
- Linux下DIR,dirent,stat等结构体详解
- 运用继承来给员工发工资
- 标准输入/输出和重定向
- 【总结】分类、聚类的评估指标
- JavaScript反选
- Gauss消元法的Matlab实现
- linux目录编程:DIR,stat, dirent结构体解析与应用
- 将图片设置为背景的图片的案例
- 学习c程的一点点感想
- mysql外键约束解释说明
- leetcode 695 题解
- 用java写一个简单的计算器详解代码
- 11月5日
- Bluetooth 蓝牙 操作
- Trie