LV04-04-文件操作-文件属性与目录
本文主要是C语言——文件属性与目录的基本操作的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
Windows | windows11 |
Ubuntu | Ubuntu16.04的64位版本 |
VMware® Workstation 16 Pro | 16.2.3 build-19376536 |
SecureCRT | Version 8.7.2 (x64 build 2214) - 正式版-2020年5月14日 |
开发板 | 正点原子 i.MX6ULL Linux阿尔法开发板 |
uboot | NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03) |
linux内核 | linux-4.15(NXP官方提供) |
STM32开发板 | 正点原子战舰V3(STM32F103ZET6) |
点击查看本文参考资料
参考方向 | 参考原文 |
--- | --- |
一、目录访问
1. 两个结构体
1.1 DIR
DIR 结构体与 FILE 类似,只是 DIR 存放的是目录相关信息的成员,它的结构,说实话,我只找到了它在 dirent.h 头文件中的声明,详细的结构还是网上搜到的:
1 | struct __dirstream |
1.2 dirent
dirent 结构体不仅仅指向目录,还可以指向目录中的具体文件。直接 man 看不到它的定义,使用 man readdir 时可以看到这个结构体定义:
1 | struct dirent |
2. 基本函数
2.1 opendir()
在 linux 下可以使用 man 3 opendir 命令查看该函数的帮助手册。
1 | /* 需包含的头文件 */ |
【函数说明】该函数打开参数 name 指定的目录, 并返回 DIR* 形态的目录流,。
【函数参数】
- name :需要打开的目录名称(可包括路径名)。
【返回值】返回值是 DIR * 类型,成功时返回目录流指针;出错时返回 NULL 。
【使用格式】一般情况下基本使用格式如下:
1 | /* 需要包含的头文件 */ |
【注意事项】 none
2.2 readdir()
在 linux 下可以使用 man 3 readdir 命令查看该函数的帮助手册。
1 | /* 需包含的头文件 */ |
【函数说明】该函数读取目录流中的内容。
【函数参数】
- dirp :已打开目录的目录流指针变量。
【返回值】返回值是 struct dirent * 类型, struct dirent 是用来描述目录流中一个目录项的结构体类型。成功时返回目录流 dirp 中的下一个目录项(下个目录进入点);出错或到末尾时返回 NULL 。
【使用格式】一般情况下基本使用格式如下:
1 | /* 需要包含的头文件 */ |
【注意事项】 none
2.3 closedir()
在 linux 下可以使用 man 3 closedir 命令查看该函数的帮助手册。
1 | /* 需包含的头文件 */ |
【函数说明】该函数关闭已打开的目录文件。
【函数参数】
- dirp :已打开目录的目录流指针变量。
【返回值】返回值是 int 类型。成功时返回 0 ;出错时返回 EOF 。
【使用格式】一般情况下基本使用格式如下:
1 | /* 需要包含的头文件 */ |
【注意事项】 none
3. 使用实例
点击查看实例
1 | /** ===================================================== |
在终端执行以下命令编译程序:
1 | gcc test.c -Wall # 生成可执行文件 a.out |
二、文件访问
1. 文件权限
Linux/Unix 的文件调用权限分为三级 : 文件所有者( Owner )、用户组( Group )、其它用户( Other Users )。只有文件所有者和超级用户可以修改文件或目录的权限。
file type | - | 代表文件 |
d | 代表目录 | |
Owner Group Other Users |
r | read(可读) |
w | write(可写) | |
x | execute(可执行) | |
- | 无权限 |
例如:
对于文件的权限还可以使用三位 8 进制数表示:
2. 基本函数
2.1 chmod()
在 linux 下可以使用 man 2 chmod命令查看该函数的帮助手册。
1 | /* 需包含的头文件 */ |
【函数说明】该函数用于修改文件权限。
【函数参数】
- pathname :需要修改权限的文件的文件名(可以包含路径)。
- mode :要修改的权限(一般为四位十六进制数,后三位代表要修改的权限)。
【返回值】返回值是 int 类型,成功时返回 0 ;出错时返回 EOF 。
【使用格式】一般情况下基本使用格式如下:
1 | /* 需要包含的头文件 */ |
【注意事项】
(1)在虚拟机中使用 Linux 时,修改共享文件夹 /mnt/hgfs/file_name 中的文件权限可能会无效,因为这里边的文件同时也是 Windows 下的文件。
(2)可以在终端使用: ll file_name 命令来单独查看某个文件的权限 。
2.2 fchmod()
在 linux 下可以使用 man 2 fchmod命令查看该函数的帮助手册。
1 | /* 需包含的头文件 */ |
【函数说明】该函数修改文件描述符 fd 指向文件的文件权限。
【函数参数】
- fd :文件描述符。
- mode :要修改的权限(一般为四位十六进制数,后三位代表要修改的权限)。
【返回值】 返回值是 int 类型,成功时返回 0 ;出错时返回 EOF 。
【使用格式】一般情况下基本使用格式如下:
1 | /* 需要包含的头文件 */ |
【注意事项】 none
3. 使用实例
点击查看实例
1 | /** ===================================================== |
在终端执行以下命令编译程序:
1 | gcc test.c -Wall # 生成可执行文件 a.out |
三、文件属性
1. stat 结构体
我们可以在linux内核源码的 include/uapi/asm-generic/stat.h中找到这个结构体。 这个结构体成员是文件的各种信息:
1 | struct stat { |
其中主要就是st_mode这个成员,它包含了文件的类型和存取的权限。 st_mode 中有 9 位是代表文件的权限的,我们可以将 1 左移再与 st_mode 做 & 运算,即可判断每位为 1 或者为 0 。
点击查看 st_mode 文件权限部分
S_ISUID | 04000 | set-user-ID bit |
S_ISGID | 02000 | set-group-ID bit |
S_ISVTX | 01000 | sticky bit |
S_IRWXU | 00700 | owner has read, write, and execute permission |
S_IRUSR | 00400 | owner has read permission |
S_IWUSR | 00200 | owner has write permission |
S_IXUSR | 00100 | owner has execute permission |
S_IRWXG | 00070 | group has read, write, and execute permission |
S_IRGRP | 00040 | group has read permission |
S_IWGRP | 00020 | group has write permission |
S_IXGRP | 00010 | group has execute permission |
S_IRWXO | 00007 | others (not in group) have read, write, and execute permission |
S_IROTH | 00004 | others have read permission |
S_IWOTH | 00002 | others have write permission |
S_IXOTH | 00001 | others have execute permission |
系统提供了一些宏,可以用这些宏来识别 st_mode 的值,以判定文件的类型和权限。我们可以直接通过宏的返回值判断文件的类型,也可以使用 st_mode & S_IFMT 的值来判断文件类型,例如,
1 | stat(pathname, &sb); |
点击查看判断 st_mode 文件类型的宏
S_IFMT | 0170000 | 文件类型位字段的位掩码 |
S_IFSOCK | 0140000 | S_ISSOCK(st_mode) 是否SOCKET文件,是返回1,否则返回0 |
S_IFLNK | 0120000 | S_ISLNK(st_mode) 是否链接文件,是返回1,否则返回0 |
S_IFREG | 0100000 | S_ISREG(st_mode) 是否常规文件,是返回1,否则返回0 |
S_IFBLK | 0060000 | S_ISBLK(st_mode) 是否块设备,是返回1,否则返回0 |
S_IFDIR | 0040000 | S_ISDIR(st_mode) 是否目录,是返回1,否则返回0 |
S_IFCHR | 0020000 | S_ISCHR(st_mode) 是否字符设备,是返回1,否则返回0 |
S_IFIFO | 0010000 | S_ISFIFO(st_mode) 是否FIFO文件,是返回1,否则返回0 |
2. 基本函数
2.1 stat()
在 linux 下可以使用 man 2 stat 命令查看该函数的帮助手册。
1 | /* 需包含的头文件 */ |
【函数说明】该函数用于获取文件信息。
【函数参数】
- pathname :文件名(可以包含路径)。
- statbuf : struct stat 类型的结构体,用于存放文件属性信息。
【返回值】返回值是 int 类型,成功时返回 0 ;出错时返回 EOF 。
【使用格式】一般情况下基本使用格式如下:
1 | /* 需要包含的头文件 */ |
【注意事项】 如果 pathname 是符号链接,那么 stat 获取的是目标文件的属性。
2.2 lstat()
在 linux 下可以使用 man 2 lstat 命令查看该函数的帮助手册。
1 | /* 需包含的头文件 */ |
【函数说明】该函数用于获取文件信息。
【函数参数】
- pathname :文件名(可以包含路径)。
- statbuf : struct stat 类型的结构体,用于存放文件属性信息。
【返回值】返回值是 int 类型,成功时返回 0 ;出错时返回 EOF 。
【使用格式】一般情况下基本使用格式如下:
1 | /* 需要包含的头文件 */ |
【注意事项】 如果 pathname 是符号链接,那么 lstat 获取的是链接文件的属性。
2.3 fstat()
在 linux 下可以使用 man 2 fstat 命令查看该函数的帮助手册。
1 | /* 需包含的头文件 */ |
【函数说明】该函数可以由文件描述符取得文件状态。
【函数参数】
- fd :已经打开文件的文件描述符。
- statbuf : struct stat 类型的结构体,用于存放文件属性信息。
【返回值】返回值是 int 类型,成功时返回 0 ;出错时返回 EOF 。
【使用格式】一般情况下基本使用格式如下:
1 | /* 需要包含的头文件 */ |
【注意事项】 none
3. 使用实例
点击查看实例
1 | /** ===================================================== |
在终端执行以下命令编译程序:
1 | gcc test.c -Wall # 生成可执行文件 a.out |