1 文件属性包括:
1:包含文件的设备的ID
2 inode号,文件系统识别文件唯一标识
3 文件类型和权限
4 硬链接号
5 用户ID
6 组ID
7 硬件设备号(若是特殊文件)
8 文件大小,以字节为单位
9 块字节大小
10 块的个数
11 最后一次被访问的时间
12 最后一次权限修改时间
13 最后一次状态修改时间
函数原型:int stat(const char*pathname,struct stat *statbuf);
功能:获取文件的属性信息
参数1:要获取属性的文件路径
参数2:struct stat: 文件属性结构体指针,该结构体中包含了文件
===================================================================
文件属性结构体指针
struct stat {
dev_t st_dev;/* ID of device containing file */ //包含文件的设备的ID
ino_t st_ino;/* Inode number */ //inode号,文件系统识别文件的唯一标识
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) */ //硬件设备号(如果是特殊文件)
off_t st_size; /* Total size, in bytes */ //文件大小,以字节为单位
blksize_t st_blksize; /* Block size for filesystem I/O */ //块字节大小
blkcnt_t st_blocks; /* Number of 512B blocks allocated */ //块的个数
/* Since Linux 2.6, the kernel supports nanosecond
precision for the following timestamp fields.
For the details before Linux 2.6, see NOTES. */
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 */ //最后一次状态修改时间
};
终端命令:man 7 inode
使用结构体的mode_t st_mode参数能够获得文件的类型与权限
- st mode&S_IFMT ------------>能够得到文件类型
S_IFSOCK 套接字文件
S_IFLNK软连接文件
S_IFREG 普通文件
S_IFBLK 块设备文件
S_IFDIR 目录文件
S_IFCHR 字符设备文件
S_IFIFO 管道文件
- 使用函数 ------------>能够得到文件类型
- st_mode&0777 —>得到文件权限
分类专栏: Linux学习记录 文章标签: linux 学习 运维
版权
Linux学习记录
专栏收录该内容
23 篇文章0 订阅
订阅专栏
Linux 学习记录23(IO篇+静/动态库+多进程理论)
本文目录
Linux 学习记录23(IO篇+静/动态库+多进程理论)
一、文件状态获取(stat)
1. 获取文件属性信息
2. 文件类型与权限
3. 使用函数打印部分文件信息到终端
二、对目录的操作
1. 打开目录
2. 读取目录下的内容
3. 关闭目录
4. 目录操作的实例
三、Linux系统中的库
1. 静态库
(1. 静态库的创建
2. 动态库
(1. 动态库的创建
四、多进程理论
1. 进程的概念
2. `进程的内存管理 (重点!!!)`
3. 程序和进程的区别
4. 进程的组成
5. 进程的种类
6. 进程的PID概念
思维导图
练习
1. 完成ls -la功能
一、文件状态获取(stat)
1. 获取文件属性信息
文件属性包括:
1. 包含文件的设备的ID
2. inode号,文件系统识别文件的唯一标识
3. 文件类型和权限
4. 硬链接号
5. 用户ID
6. 组ID
7. 硬件设备号(如果是特殊文件)
8. 文件大小,以字节为单位
9. 块字节大小
10. 块的个数
11. 最后一次被访问的时间
12. 最后一次权限修改时间
13. 最后一次状态修改时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
函数原型:int stat(const char*pathname,struct stat *statbuf);
功能:获取文件的属性信息
参数1:要获取属性的文件路径
参数2:struct stat: 文件属性结构体指针,该结构体中包含了文件
===================================================================
文件属性结构体指针
struct stat {
dev_t st_dev;/* ID of device containing file */ //包含文件的设备的ID
ino_t st_ino;/* Inode number */ //inode号,文件系统识别文件的唯一标识
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) */ //硬件设备号(如果是特殊文件)
off_t st_size; /* Total size, in bytes */ //文件大小,以字节为单位
blksize_t st_blksize; /* Block size for filesystem I/O */ //块字节大小
blkcnt_t st_blocks; /* Number of 512B blocks allocated */ //块的个数
/* Since Linux 2.6, the kernel supports nanosecond
precision for the following timestamp fields.
For the details before Linux 2.6, see NOTES. */
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 */ //最后一次状态修改时间
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2. 文件类型与权限
终端指令:man 7 inode
1
man手册:
使用结构体的mode_t st_mode参数能够获得文件的类型与权限
st mode&S_IFMT ------------>能够得到文件类型
S_IFSOCK 套接字文件
S_IFLNK软连接文件
S_IFREG 普通文件
S_IFBLK 块设备文件
S_IFDIR 目录文件
S_IFCHR 字符设备文件
S_IFIFO 管道文件
使用函数 ------------>能够得到文件类型
st_mode&0777 —>得到文件权限
3. 使用函数打印部分文件信息到终端
int main(int argc, char const *argv[])
{
struct stat sb;
/*获取文件属性*/
stat("./01file.txt", &sb);
/*类型*/
switch(sb.st_mode&__S_IFMT)
{
case __S_IFSOCK : printf("flie type: 套接字文件\n"); break;
case __S_IFLNK : printf("flie type: 软连接文件\n"); break;
case __S_IFREG : printf("flie type: 普通文件\n"); break;
case __S_IFBLK : printf("flie type: 块设备文件\n"); break;
case __S_IFDIR : printf("flie type: 目录文件\n"); break;
case __S_IFCHR : printf("flie type: 字符设备文件\n"); break;
case __S_IFIFO : printf("flie type: 管道文件\n"); break;
default : break;
}
/*权限*/
printf("flie mode: %#o\n",sb.st_mode&0777);
/*大小*/
printf("flie size: %ld byte\n", sb.st_size);
/*inode号*/
printf("flie inode ID: %ld\n",sb.st_ino);
return 0;
}
输出>>
flie type: 普通文件
flie mode: 0664
flie size: 155 byte
flie inode ID: 529027
终端查看文件结果:
二、对目录的操作
1. 打开目录
函数原型:DIR *opendir(const char *name);
功能:通过指定的路径打开一个目录
参数1:目录的路径
返回值:成功返回DIR*的目录指针,失败返回NULL并置位错误码
======================================================
2. 读取目录下的内容
函数原型:struct dirent *readdir(DIR *dirp);
功能:通过指定的目录指针读取出一条文件的信息,将信息放置于struct dirent类型的指针中
通过该指针获取文件的信息
参数1:指定的目录指针
返回值:成功返回struct dirent的结构体指针,失败返回NULL并置位错误码
每读取一次向下偏移一次
======================================================
struct dirent {
ino_t d_ino;/* Inode number */ //inode号
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 */ //文件名
};
========================================================
文件类型:
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.
3. 关闭目录
函数原型:int closedir(DIR *dirp);
功能:关闭当前目录
参数1:指定的目录指针
返回值:成功返回0,失败返回-1并置位错误码
4. 目录操作的实例
int main(int argc, char const *argv[])
{
DIR* dp;
if((dp=opendir("./"))==NULL)
{
perror("opendir: ");
return -1;
}
struct dirent* tp;
while((tp = readdir(dp)) != NULL)
{
printf("%s\t",tp->d_name);
printf("%c\t",tp->d_type);
printf("%-4d\t",tp->d_reclen);
printf("%ld\t",tp->d_ino);
printf("\r\n");
}
return 0;
}
一,linux系统中的库
1> linux系统中的库本质上是一个二进制文件,由.c文件(不含main)编译而来,其他程序可以使用该库调用相关函数
2 > 分类:静态库 动态库
3 > 不同的操作系统对应的库的格式有所不同
windows:XXX.lib(静态库)
XXX.dll(动态库)
linux:libXXX.a(静态库)
libxxx.so(动态库)
4 >由于库是二进制文件,.c文件编译生成库,函数的实现过程是看不到的,所以使用库比较安全
1.1静态库
将XXX.c文件编译生成的一个库名为.a的二进制文件,当你需要使用该库中的某个函数时,直接调用该函数即可,前提是编译时链接了该库,静态体现在:在使用gcc编译时,会将你的文件和库文件一起生成一个可执行文件,在最终的可执行程序中,包含了静态库,程序的体积一般比较大,在执行程序的过程中,就无须取找该库所在的位置,效率较高
编译生成静态库
1 gcc -c add.c -o add.o //只编译不链接 将源文件生成2进制文件
2 ar -cr libadd.a add.o //ar说明这是做静态库的指令
//如果由多个.o文件生成一个静态库 ar -crs 库名.a add1.o add2.o ...
库名命名规范:以lib开头,后面是库名,最后以.a结尾
例如:xxx.c生成的库名:libxxx.a
1.2动态库
将XXX.c文件编译生成的一个库名为.a的二进制文件,当你需要使用该库中的某个函数时,直接调用该函数即可,前提是编译时链接了该库,静态体现在:在使用gcc编译时,会将你的文件和库文件的索引表一起生成一个可执行文件,程序的体积一般比较大,在执行程序的过程中,就须取找该库所在的位置,效率较低。但是由多个程序共享一个库,动态库又称共享库。
解决报错办法:
二,多进程
2.1 进程的概念
进程:程序的一次执行过程
进程就是一个动态的过程,是有生命周期的,随着进程的创建而出现,随着进程的UAN的消亡而销毁
进程是分配资源的最小单位 每个进程都会拥有自己的0-3G 的用户空间 但是共享3-4G的内核空间
这0-3G 的用户空间又被分为三个部分 栈区 堆区 静态区
进程在内核空间有一个task_struct表示
2.2进程的内存管理(重点!!!)
1>每个进程都会被分配4G的空间
2> 每个进程都拥有自己的0-3G的用户空间,3--4G的内核空间是共享的
2.3程序和进程的区别
进程:进程是动态的,有生命周期,是程序的一次执行过程,每个进程拥有0-3G的用户空间,并且共享3-4G的内核空间
程序:程序是静态的,没有生命周期可言,它是在磁盘上的一个二进制文件
2.4 进程的组成
进程有三部分组成:进程控制段,数据段,程序段
进程控制段:是内核空间分配的一个task_struct的结构体,包含了一个进程的所有信息:PID,进程的状态,相关寄存器
数据段:在进程执行过程中,中间数据存放的位置:.data .bss
程序段:存放程序允许的代码:.text
2.5 进程的种类
进程一共有三种:交互进程,批处理进程,守护进程
交互进程:它是由shell脚本控制,可以直接和用户进行交互的进程,例如文本编辑器
批处理进程:维护了一个队列,被放到该队列中的进程会被统一处理,例如终端执行./a.out
守护进程:脱离终端而存在,例如服务进程
2.6进程的PID概念
进程号:PID 计算机系统识别进程的唯一标识
父进程号:PPID
无论是PID还是PPID都是一个大于等于0的数字1.
1. 完成ls -la功能(转载)
int main(int argc, char const *argv[])
{
DIR* dp;
struct stat sb;//获取文件详情
struct tm* file_time;
int i = 0;
int z = 0;
int buff=0;
int buff1=0;
char power[11]={0};//权限
char file_name[50]={'.','/'};//文件名
if((dp=opendir("./"))==NULL)
{
perror("opendir: ");
return -1;
}
struct dirent* tp;
while((tp = readdir(dp)) != NULL)
{//循环查看文件夹下的文件
buff1=0x100;
z=0;
strcpy(file_name+2,tp->d_name);
/*获取文件属性*/
stat(file_name, &sb);
file_time = localtime(&sb.st_ctime);//计算文件时间
switch(sb.st_mode&__S_IFMT)
{
case __S_IFSOCK : power[0] = 's'; break;//套接字文件
case __S_IFLNK : power[0] = 'l'; break;//软连接文件
case __S_IFREG : power[0] = '-'; break;//普通文件
case __S_IFBLK : power[0] = 'b'; break;//块设备文件
case __S_IFDIR : power[0] = 'd'; break;//目录文件
case __S_IFCHR : power[0] = 'c'; break;//字符设备文件
case __S_IFIFO : power[0] = 'p'; break;//管道文件
default : break;
}
buff=sb.st_mode&0777;
for(i=1;i<10;i++)
{
z++;
if(z>3) z=1;
// printf("%#x\r\n",buff1);
switch(z)
{
case 1 : (buff&buff1)?(power[i] = 'r'):(power[i] = '-'); break;
case 2 : (buff&buff1)?(power[i] = 'w'):(power[i] = '-'); break;
case 3 : (buff&buff1)?(power[i] = 'x'):(power[i] = '-'); break;
}
buff1=buff1>>1;
}
printf("%s ",power);//链接号
printf("%3ld ",sb.st_nlink);//链接号
printf("%5d ",sb.st_uid);//所属用户
printf("%5d ",sb.st_gid);//所属组用户
printf("%7ld ",sb.st_size);//文件大小
printf("%.2dmon ",file_time->tm_mon+1);//文件最后修改日期(月)
printf("%.2dday ",file_time->tm_mday);//文件最后修改日期(日)
printf("%.2d:",file_time->tm_hour);//文件最后修改日期(时)
printf("%.2d ",file_time->tm_sec);//文件最后修改日期(时)
printf("%s",file_name+2);//文件名
printf("\r\n");//换行
}
return 0;
}
运行结果>>
drwxrwxr-x 6 1000 1000 4096 05mon 29day 08:56 ..
-rw-rw-r-- 1 1000 1000 427 05mon 29day 13:51 public.h
-rwxrwxr-x 1 1000 1000 12848 05mon 29day 20:22 main.out
drwxrwxr-x 2 1000 1000 4096 05mon 29day 08:56 .vscode
-rw-rw-r-- 1 1000 1000 0 05mon 29day 09:17 02file.txt
-rw-rw-r-- 1 1000 1000 19 05mon 29day 08:56 public.c
-rw-rw-r-- 1 1000 1000 2362 05mon 29day 20:19 main.c
drwxrwxr-x 3 1000 1000 4096 05mon 29day 20:22 .
-rw-rw-r-- 1 1000 1000 155 05mon 29day 09:23 01file.txt
-rw------- 1 1000 1000 380928 05mon 29day 08:56 core
终端结果: