虚拟地址通过页表映射到屋里内存,页表由操作系统维护并被处理器引用。
分为用户段(0~3G)和内核段(3G ~ 4G), 如下图所示。
Ref
def: Linux 系统中,把一切都看做是文件,当进程打开现有文件或创建新文件时,内核向进程返回一个文件描述符,文件描述符就是内核为了高效管理已被打开的文件所创建的索引,用来指向被打开的文件,所有执行I/O操作的系统调用都会通过文件描述符。
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> /* int open(const char *pathname, int flags); 打开一个已经存在的文件 - pathname: 文件路径 - flags: 对文件的操作权限设置 O_RDONLY、O_WRONLY,ORDWR 三个设置是互斥的 errno:属于 Linux 系统函数库,库中定义全局变量,记录的是最近的错误号。 perror(const char *s):打印 error 对应的错误描述 int open(const char *pathname, int flags, mode_t mode); 创建一个新的文件 -pathname: 要创建的文件路径 -flags:文件的操作权限和其他设置, 同上, O_CREAT,文件不存在,创建新文件 - mode: 八进制数 最终权限是 mode & ~umask, umask 0002, ~umask 0775 0777 & 0775 = 0775 umask作用:抹去某些权限, 其他组不可以进行写的操作 */ int main(int argc, char *argv[]) { // int fd = open("a.txt", O_RDONLY); // if (fd == -1) { // perror("open failed"); // } // close(fd); int fd = open("create.txt", O_RDWR | O_CREAT, 0777); if (fd == -1) { perror("create failed"); } close(fd); return 0; }
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdbool.h> #include <stdlib.h> #include <string.h> /* ssize_t read(int fd, void *buf, size_t count); - fd: 文件描述符 - buf:缓冲区,读取数据存放的地方,数组的地址 - count:指定的数组的大小 返回值: > 0: 返回实际读取的大小字节 =0:文件已经读完了 -1: 失败 ssize_t write(int fd, const void *buf, size_t count); - fd: 文件描述符 - buf:缓冲区,要往磁盘写入的数据 - count:要写的数据的实际大小 返回值: > 0: 实际写入的字节大小 -1: 失败 */ void errif(bool flag, const char *msg) { if (flag) { perror(msg); exit(EXIT_FAILURE); } } int main() { // open打开文件 int src_fd = open("./create.txt", O_RDONLY); errif(src_fd == -1, "open failed"); // 创建一个新的文件 int dest_fd = open("copy.txt", O_WRONLY | O_CREAT, 0664); errif(dest_fd == -1, "open failed"); // 频繁的读写操作 char buf[1024]; bzero(&buf, sizeof(buf)); int len = 0; while ((len = read(src_fd, buf, sizeof(buf))) > 0) { write(dest_fd, buf, len); } // 关闭文件 close(src_fd); close(dest_fd); return 0; }
lseek(fd, 0, SEEK_SET)
lseek(fd, 0, SEEK_CUR)
lseek(fd, 0, SEEK_END)
lseek(fd, 100, SEEK_END)
#include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <fcntl.h> /* off_t lseek(int fd, off_t offset, int whence); fd: 文件描述符,通过 open 得到的 offset: 偏移量 whence: SEEK_SET 设置文件指针偏移量(文件开始处) The file offset is set to offset bytes. SEEK_CUR 设置偏移量:当前位置 + 第二个参数 offset The file offset is set to its current location plus offset bytes. SEEK_END 文件大小 + 第二个参数 offset The file offset is set to the size of the file plus offset bytes. 返回文件指针所在位置 移动文件指针到文件头 lseek(fd, 0, SEEK_SET); 获取当前文件指针的位置 lseek(fd, 0, SEEK_CUR); 获取文件长度 lseek(fd, 0, SEEK_END); 拓展文件的长度,当前文件 10b,增加 100 字节 100 字节 */ int main() { int fd = open("create.txt", O_RDWR); if (fd == -1) { perror("open failed"); return -1; } int ret = lseek(fd, 100, SEEK_END); if (ret == -1) { perror("lseek failed"); return -1; } write(fd, " ", 1); close(fd); return 0; }