文章目录
1.GCC编码过程
2.是否定义宏
//如果定义宏就执行当前内容
#ifdef 宏名
内容;
//如果没有就执行下方内容
#endif
内容;
3. 库作用
- 代码保护(反编译无法编译部分内容)
- 方便部署和分发
4.文件IO
结构体:
- 文件描述符(整形,__fileno) -> 文件位置
- 文件读写指针 -> 操作数据
- I/O缓冲区 -> 先缓冲,再一次性修改,也可以用fflush强制写入)
5.虚拟地址空间
- 32位机器(2的32次方等于4G) 0-3G 用户区 3G-4G 内核区(普通用户无权限)
- 虚拟地址到物理地址 -> MMU(内存管理单元)
- 内核访问数据需要进行系统调用API
- .data(数据段) 初始化的全局变量,静态的局部变量
- 堆. 动态分配内存
- 共享库: 存储映射区
- 栈空间: 局部变量(10M左右),从上往下分配地址
- 命令行: 函数起始的地址
- 用户态切换到内核态有三种方式: 系统调用,中断,异常. 只有系统调用是主动
6.文件描述符
- PCB里面的一个数组,起到文件标识符作用
- 数组大小默认1024
- 前三个是固定占用的(标准输入/输出/错误 对于当前同一个终端 )
- 存在内核区,由内核管理
7.Linux系统
1.I/O函数
//c语言没有重载,所以在此处是可变参
int open(const char *pathname,int flags);
/*打开一个已经存在的文件
参数:
1. 路径
2. 32位数据,对文件的权限操作设置,每个标记一位
必选:O_RDONLY,O_WRONIT,PRDWR
返回值:成功文件描述符(int型),出错就返回-1,置errno
*/
int open(const char *pathname,int flags,mode_t mode);
/*创建一个已经存在的文件
参数:
1. 路径
2. 32位数据,对文件的权限操作设置,每个标记一位
必选:O_RDONLY,O_WRONIT,PRDWR
可选:用|隔开, O_CREAT(创建),O_APPEND(追加)...
3. 八进制数,表示用户对新文件的操作权限(0000-rwx)
最终权限(mode & ~umake(直接在当前目录下输入umake可得到))
返回值:成功文件描述符(int型),出错就返回-1,置errno
*/
int close(int fd)
//关闭文件,清理文件描述符
<unistd.h>
ssize_t read(int fd,void *buf,size_t count)
/*
读取文件大小为conut的内容,存到buf中.
参数:
1. 文件描述符,由open()得到
2. 需要读取数据存放的地方,一般为数组的地址(存放读取的数据)
3. 指定的数组大小
返回值:
成功返回读取到的字节大小,返回0就是到文件末尾.
失败为-1,置errno
*/
ssize_t write(int fd,const void *buf,size_t count)
/*
写大小为conut的buf内容到文件中.(count可能比buf容量小)
参数:
1. 文件描述符,由open()得到
2. 放需要写入的内容
3. 指定写入的大小
返回值:
成功返回实际写入的大小,返回0就是没有内容写入.
失败为-1,置errno
*/
off_t lseek(int fd,off_t offest,int whence)
/*
对文件描述符指向的文件进行偏移操作
参数:
1. 文件描述符,由open()得到
2. 偏移量
3. [SEEK_SET(0 + offest)|SEEK_CUR(当前位置 + offest)|SEEK_END(文件大小 + offest)]
返回值: 文件指针最终的位置
作用:
1. 移动到文件开头 lseek(fd,0,SEEK_SET);
2. 获取当前文件指针位置 lseek(fd,0,SEEK_CUR);
3. 获取文件长度 lseek(fd,0,SEEK_END);
4. 扩展文件长度(字节) lseek(fd,100,SEEK_END);
-可以在写入之前先扩展好,避免出现写一半内存不足.扩展后写入一个空数据(write(fd," ",1);)
*/
int stat(const char *pathname,struct stat *statbuf);
/*
返回关于文件的信息,信息放到statbuf中
参数:
1. 路径
2. statbuf 结构体参数,用来存储文件信息.具体如下
3. 成功返回0,失败为-1,置errno
*/
int lstat(const char *pathname,struct stat *statbuf);
//与前面一样,只是在软连接文件的时候获取的是软连接文件而不是源文件
statbuf结构体
//判断文件类型和权限
(st.mode & S_IFMT) == S_IFREF(宏定义)
2.文件属性操作
int access(const char* pathname,int mode);
/*
判断文件权限或是否存在
参数:
1. 路径
2. 判断是否对文件具有(读R_OK,写W_OK,执行X_OK,是否存在F_OK)的权限
返回值:成功0,失败-1置errno.
*/
int chmod(const char* filename,mode_t mode);
/*
修改权限
参数:
1. 文件路径
2. 权限-八进制数(0000~0777);
返回值:成功0,失败-1置errno.
*/
int chown(const char* path,uid_t owner,gid_t group);
/*
修改文件所在组
参数:
1. 文件路径
2. 用户id(vim /etc/password)
3. 要变换到的组id
返回值:成功0,失败-1置errno.
*/
int truncate(const char* path,off_t length);
/*
缩减或扩展文件大小
参数:
1. 路径
2. 需要最终文件的大小
返回值:成功0,失败-1置errno.
*/
3.目录操作函数
int mkdir(const char*pathname,mode_t mode);
/*
创建目录
参数:
1. 文件路径
2. 权限-八进制数(0000~0777) & umask;
返回值:成功0,失败-1置errno.
*/
int rmdir(const char*pathname);
/*
删除空目录
返回值:成功0,失败-1置errno.
*/
int rename(const char* oldpath,const char *newpath);
/*
目录重命名
参数
1. 旧名称
2. 新名称
返回值:成功0,失败-1置errno.
*/
int chdir(const char* path);
/*
修改进程的工作路径(修改相对路径起始位置)
参数:
1. 要修改的工作目录
返回值:成功0,失败-1置errno.
*/
char *getchar(const char *buf,size_t size);
/*
获取当前路径
参数:
1. buf保存结果,数组
2. 数组大小
返回值:数组的地址
*/
DIR *opendir(const char *name);
/*
打开目录
参数
1. 打开目录的名称
返回值: DIR* 目录流信息
*/
struct dirent *readdir(DIR *dirp);
/*
读取目录
参数
1. 目录流信息 opendir()获得
返回值:成功返回dirent结构体,下方给出
失败或者为空返回NULL
*/
int closedir(DIR *dirp);
/*
关闭目录
*/
4.dup/dup2/fcntl函数
int dup(int oldfd);
/*
复制文件描述符(在最小的数组位置上复制一份文件描述符)
参数
1. 待复制的文件描述符,指向同一个文件
返回值:成功返回新的文件描述符,失败-1置errno.
*/
int dup2(int oldfd,int newfd);
/*
重定向文件描述符,让newfd = oldfd,也就是指向同一个文件
返回值:成功返回复制后的新的文件描述符(newfd == 返回值,所以只需要关闭一个),失败-1置errno.
*/
int fcntl(int fd,int cmd,.../*arg可变参数*/);
/*
复制文件描述符
设置/获取文件的状态标志
参数:
1. 文件描述符
2. 表述对文件描述符做的操作
- F_DUPFD : 复制文件描述符,返回一个新的fd
- F_GETFL : 获取文件描述符的flags(open设置的,读写)
- F_SETFL : 设置文件描述符的flags(必选可选都与open相同),在后续的可变参写入
也可以设置NONBLOK(非阻塞). 会不会阻塞当前线程
修改一般步骤, 先获取当前文件描述符的flags,然后或上新的,再重新设置即可;
*/
版权声明:本文为weixin_46282078原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。