一、Linux 系统的目录结构
Linux系统的一个目录中包含多个目录项,每个目录项中包含一个I-Node结点与目录文件名一,一对应.
二、linux 系统目录操作
1.打开目录 -> 2.读取目录 -> 3.关闭目录
1、opendir 打开目录
man 3 opendir 查看目录打开函数
NAME
opendir, fdopendir - open a directory
SYNOPSIS
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
name:需要打开的目录路径名
返回值:成功 目录指针 失败 NULL
例子:打开一个目录
DIR *dp = opendir("./mydir");
if (dp == NULL)
{
printf("打开目录失败\n");
return -1;
}
2、readdir 读取目录项信息
man 3 查看读取目录项函数
NAME
readdir - read a directory
SYNOPSIS
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
dirp:需要读取的目录指针
返回值:成功 目录项信息结构体
失败 NULL
目录项信息结构体
struct dirent {
ino_t d_ino; /* Inode number I-NODE节点号*/
off_t d_off; /* Not an offset; see below 目录偏移量*/
unsigned short d_reclen; /* Length of this record 目录项大小*/
unsigned char d_type; /* Type of file; not supported ⭐文件类型
by all filesystem types */
char d_name[256]; /* Null-terminated filename ⭐文件名*/
};
例子:读取目录项
struct dirent *p = readdir(dp);
printf("文件名 %s\n",p->d_name);
例子:判断文件类型
DT_BLK This is a block device. 块设备
DT_CHR This is a character device. 字符设备
DT_DIR This is a directory. 目录
DT_FIFO This is a named pipe (FIFO). 管道
DT_LNK This is a symbolic link. 链接
DT_REG This is a regular file. 普通文件
DT_SOCK This is a UNIX domain socket. 网络文件
DT_UNKNOWN The file type could not be determined. 不知道啥类型
struct dirent *p = readdir(dp);
if(p->d_type == DT_DIR) //判断是否为目录
...
if(p->d_type == DT_REG) //判断是否为普通文件
.....
3、closedir 关闭一个目录
NAME
closedir - close a directory
SYNOPSIS
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
4、创建与删除目录
NAME
mkdir, mkdirat - create a directory
功能: 创建一个目录
SYNOPSIS
#include <sys/stat.h>
#include <sys/types.h>
int mkdir(const char *pathname, mode_t mode); //创建目录函数
pathname:创建的目录路径名
mode:权限 👉0777
返回值:成功 0 失败 -1
NAME
rmdir - delete a directory
删除一个空目录
SYNOPSIS
#include <unistd.h>
int rmdir(const char *pathname);
pathname:需要删除的目录名称
int rename(const char *oldpath, const char *newpath); //重命名一个文件
int unlink(const char *pathname); //删除断开一个文件链接
5、stat 文件属性获取(了解)
man 2 stat 查看文件属性函数
NAME
stat, fstat, lstat, fstatat - get file status
SYNOPSIS
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *statbuf);
文件属性结构体
struct stat {
dev_t st_dev; /* ID of device containing file 设备ID */
ino_t st_ino; /* Inode number i-node节点 */
mode_t st_mode; /* File type and mode 文件类型与权限 */
nlink_t st_nlink; /* Number of hard links 硬链接数 */
uid_t st_uid; /* User ID of owner 用户ID */
gid_t st_gid; /* Group ID of owner 用户组ID*/
dev_t st_rdev; /* Device ID (if special file) 设备ID */
off_t st_size; /* Total size, in bytes 文件大小 */
blksize_t st_blksize; /* Block size for filesystem I/O 建议操作(read/write)文件时的大小*/
blkcnt_t st_blocks; /* Number of 512B blocks allocated 以512字节给文件分配块数 */
struct timespec st_atim; /* Time of last access 最后一次访问 */
struct timespec st_mtim; /* Time of last modification 最后一次修改 */
struct timespec st_ctim; /* Time of last status change 最后一次状态变更*/
#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
获取设备id
unsigned int major(dev_t dev); //获取驱动主设备号
unsigned int minor(dev_t dev); //获取驱动次设备号
printf("ID of containing device: [%jx,%jx]\n",
(uintmax_t)major(sb.st_dev),
(uintmax_t)minor(sb.st_dev));
linux系统下只有驱动设备才有设备ID ,普通文件是没有设备ID的
文件权限获取
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysmacros.h>
int main(int argc, char *argv[])
{
// 定义结构体变量
struct stat sb;
if (argc != 2) // 判断参数是否正确
{
// 把argv[0]输出到标准出错设备中
fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
exit(EXIT_FAILURE); // 结束进程
}
if (stat(argv[1], &sb) == -1)
{
perror("stat"); // 打印错误信息
exit(EXIT_FAILURE);
}
// 输出文件权限
printf("Mode: %jo (octal)\n", (uintmax_t)sb.st_mode);
unsigned short mode = sb.st_mode & 0x1ff; // 提取后9位
int stack[10] = {0}; // 栈
for (int i = 0; i < 9; i++)
{
stack[i] = mode & 0x01;
mode >>= 1;
}
// 遍历栈中的数据
for (int i = 8; i >= 0; i--)
{
printf("%d\t", stack[i]);
}
}
EXAMPLES 官方使用例子
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysmacros.h>
int main(int argc, char *argv[])
{
struct stat sb;
if (argc != 2) {
fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (lstat(argv[1], &sb) == -1) {
perror("lstat");
exit(EXIT_FAILURE);
}
printf("ID of containing device: [%jx,%jx]\n",
(uintmax_t) major(sb.st_dev),
(uintmax_t) minor(sb.st_dev));
printf("File type: ");
switch (sb.st_mode & S_IFMT) {
case S_IFBLK: printf("block device\n"); break;
case S_IFCHR: printf("character device\n"); break;
case S_IFDIR: printf("directory\n"); break;
case S_IFIFO: printf("FIFO/pipe\n"); break;
case S_IFLNK: printf("symlink\n"); break;
case S_IFREG: printf("regular file\n"); break;
case S_IFSOCK: printf("socket\n"); break;
default: printf("unknown?\n"); break;
}
printf("I-node number: %ju\n", (uintmax_t) sb.st_ino);
printf("Mode: %jo (octal)\n",
(uintmax_t) sb.st_mode);
printf("Link count: %ju\n", (uintmax_t) sb.st_nlink);
printf("Ownership: UID=%ju GID=%ju\n",
(uintmax_t) sb.st_uid, (uintmax_t) sb.st_gid);
printf("Preferred I/O block size: %jd bytes\n",
(intmax_t) sb.st_blksize);
printf("File size: %jd bytes\n",
(intmax_t) sb.st_size);
printf("Blocks allocated: %jd\n",
(intmax_t) sb.st_blocks);
printf("Last status change: %s", ctime(&sb.st_ctime));
printf("Last file access: %s", ctime(&sb.st_atime));
printf("Last file modification: %s", ctime(&sb.st_mtime));
exit(EXIT_SUCCESS);
}
至此,希望看完这篇文章的你有所收获,我是Bardb,译音八分贝,道友,下期见!