LINUX C之进程内存管理与文件操作(2)

一、内存的映射

将一块物理地址映射到进程的虚拟地址空间

将一个文件映射到进程的虚拟地址空间,在虚拟地址空间进行数据改变,这些改变将同步到底层文件

mmap(2)

#include<sys/mman.h>

void *mmap(void *addr, size_t length, int prot, int flogs, int fd, off_t offset)

功能:将文件或设备映射到内存

参数:

addr:指定了映射区域的起始位置,输入NULL代表内核自动选择

length:指定映射区域的长度

prot:选择一个或者多个

①PROT_EXEC:执行

②PROT_READ:读

③PROT_WRITE:写

④PROT_NONE:无权限

flags:二选一

①MAP_SHARED(共享)

②MAP_PRIVATE(私有)

注:

物理地址空间中,有些设备没有文件名,这些设备的确是一个文件但没有记录到文件管理系统中,这类文件称为匿名文件

共享映射:对映射区域的更新可以被另外一个映射同一文件的进程看到,并且同步到底层文件中

私有映射:对映射区域的更新不能被另一个映射同一文件的进程看到,并且不同步到底层的文件中

MAP_ANOYMOUS可以或到flag标记中,表示匿名映射,此时fd被设置成-1,offset被忽略

fd:指定了文件的描述符,将此文件映射到进程的虚拟地址空间

offet:指定了文件映射的起始位置,必须是页的整数倍

返回值:

成功:返回映射区域的起始位置

失败:MAP_FAILED被返回,errno被设置

int munmap(void*addr,size_t length);

功能:解除文件或设备到内存的映射

参数:

addr:指定映射区域的起始位置

length:指定长度

返回值:

成功:返回0

失败:返回-1,errno被设置

私有映射: 

共享映射:

二、文件的元数据

文件有两部分组成:文件内容和描述信息

ls -l显示的文件属性中除文件名外都是文件的元数据

ls -li显示的最前面的数字是inode号

每个文件有且仅有一个对应的inode号

两个文件如果共用一个inode号就是硬链接

软连接:

 data中包含十五个元素的整型数组(数据块),每个块有一个编号4个字节,放数据块的地址

数据块地址指向存储空间,一般指向一页大小的存储空间,也可以开辟更多的空间,让指向的4k地址存编号,在分别指向存储空间,4k内存可以存储1k个编号,这样就可以存储1k*4k的大小空间,如果不够还可以继续这样分配

 用stat(2)来获取文件的元数据,不适用于软连接

#include<sys/types.h>

#include<sys/stat.h>

#include<unistd.h>

int stat(const char *pathname,struct stat*buf);

功能:获得指定文件的元数据

参数:

pathname:指定了要操作的文件路径

buf:将文件的元数据存储到buf指定的地址空间中

返回值:

成功返回0

错误返回-1

struct stat{

        dev_t   st_dev;//设备ID

        ino_t    st_ino;//文件对应的inode号

        mode_t  st_mode;//权限

        nlink_t    st_nlink;//硬链接数

        uid_t       st_uid;//属主ID,输出的是一串数字

        gid_t        st_gid;//属组ID,输出的是一串数字

        dev_t       st_rdev;//设备ID

        off_t         st_size;//文件尺寸

        blksize_t   st_blksize;//文件系统IO

        blkcnt_t    st_block;

        struct  timespec  st_atim;//最后访问时间,所得到的时间都是秒

        struct  timespec  st_mtim;//最后修改时间

        struct  timespec  st_ctim;//最后状态修改时间

        #define st_atime  st_atim.tv_sec

        #define st_mtime  st_mtim.tv_sec

        #define st_ctime   st_ctim.tv_sec

      };

struct timespec{

        _time_t tv_sec;

        _syscall_slong_t tv_nsec;

};

如何看结构体中定义的类型用什么占位符呢

gcc -E生成.i文件即可在.i文件中查看

用户信息存放在/etc/passwd中 ,当我们查看会发现它是冒号分割的七列数据

分别是:

用户名:用户是否有密码:用户ID:组ID:对用户的说明信息:用户家目录:用户登陆成功后执行的第一个程序

但当我们用ls -l查看文件时显示的是用户名和用户组名 

如何将uid和gid的数字转换成我们常见的用户名和用户组名的字符串形式呢

getpwuid(3)和getgrgid(3)这两个库函数可以完成

#include<sys/types.h>

#include<pwd.h>

struct passwd*getpwuid(uid_t uid)

功能:获得与uid匹配的用户数据

参数:

uid:指定uid,从文件中找与uid匹配的记录

返回值:

失败:NULL,无匹配记录,errno被设置

成功:返回地址

struct passwd{

        char *pw_name;//用户名

        char*pw_passwd;//用户名password

        char*pw_gecos;//用户信息

        uid_t pw_uid;//用户ID

        gid_t pw_gid;//用户组ID

        char*pw_dir;//用户家目录

        char*pw_shell;//shell program

}

struct group*getgrgid(gid_t gid);

功能:查找与gid匹配的记录

参数:

gid:指定要找的gid

返回值:

失败返回NULL,无匹配或错误,errno被设置

成功返回一个地址

struct group{

        char*gr_name;//组名字

        char*gr_passwd;//组密码

        gid_t gr_gid;//组ID

        char**gr_men;//组成员

}

如何转换我们所得到的时间呢,我们得到的时间是从1970年1月1日0:00开始计时的秒数

可以使用ctime这个函数来进行转换

文件权限上和类型我们想得到我们平时看的那种方式,类型用-,b,c,d等表示,权限用r、w、x、-表示该如何转换呢

类型: 

S_IFMT是类型掩码,用我们得到的st_mode&S_IFMT所得到的数下面的进行对比,是哪个对应的即是哪种类型,此外系统还定义了一组宏,也可以来查看是什么类型的文件

 权限:

 和文件类型相同,使用s_mode分别与这些宏相与,不为0代表有此权限,为0代表无此权限

下面用代码使用以下看看:

三、文件夹操作

ls -la是显示所有文件的命令,创建和删除对于文件夹来说相当于写操作,文件夹是不能执行的,所以这里的执行代表着可通过的意思,例如使用cd

如何在程序中访问文件夹的内容

opendir(3) 、closedir(3)、readdir(3)

#include<sys/types.h>

#include<dirent.h>

DIR*opendir(const char *name);

功能:打开一个文件夹

参数:文件夹名字

返回值

成功返回一个指向文件夹流的指针

失败返回NULL,errno被设置

int closedir(DIR*dirp);

功能:关闭文件夹流

参数:

dirp:要关闭的文件夹流

返回值:

成功返回0

失败返回-1,errno被设置

#include<dirent.h>

struct dirent*readdir(DIR*dirp);

功能:从文件夹流中读取一条信息

参数:指定了文件夹流

返回值:

成功返回一个指向struct dirent结构体的地址

失败返回NULL,errno被设置或者是到达文件夹末尾

 写个代码看一下

 还有一些其他的函数,不具体展开了,需要用时可以用man手册查一下

access(2)查看权限、basename(2)获取路径文件夹、dirname(3)解析路径、chdir(2)改变工作路径、getcwd(3)获取当前工作路径、mkdir(2)创建文件夹

chmod(2)改变文件权限、link(2)硬链接、unlink(2)解除硬链接、symlink(2)软链接、rename(2)改变名字或位置、remove(3)移除文件夹......

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值