在Linux系统中,打开的文件是用一个整数来表示的,表示打开文件的整数,称为文件描述符。
1.open/create
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);
flag的取值:
flag | 意义 |
O_APPEND | 追加方式 |
O_ASYNC | 异步方式 |
O_CLOEXEC | 调用exec成功后,文件描述符自动关闭 |
O_CREAT | 如果文件不存在,则创建 |
mode | 意义 | |
S_IRWXU | 00700 | 文件所有者有读写、可执行权限 |
S_IRUSR | 00400 | 用户有读权限 |
S_IWUSR | 00200 | 用户有写权限 |
S_IXUSR | 00100 | 用户有可执行权限 |
S_IRWXG | 00070 | 组有读写、可执行权限 |
S_IRGRP | 00040 | 组有读权限 |
S_IWGRP | 00020 | 组有写权限 |
S_IXGRP | 00010 | 组有可执行权限 |
S_IRWXO | 00007 | 其它用户有读写、可执行权限 |
S_IROTH | 00004 | 其它用户有读权限 |
S_IWOTH | 00002 | 其它用户有写权限 |
S_IXOTH | 00001 | 其它用户有可执行权限 |
int close(int fd);关闭文件
int dup(int oldfd);
dup函数可以复制文件描述符,让两个文件描述符指向同一个文件结构。通过dup复制文件描述符和两次打开文件描述符不同,所以两个文件描述符共享一个文件指针。当一个文件描述符被关闭时,关闭的是内核的文件描述结构,但是如果文件描述结构体中,引用计数器不为1,那么close函数就只是减少了引用计数器而已。
3.read/write
ssize_t read(int fd, void *buf, size_t count);
ssize_t read(int fd, void *buf, size_t count);
读写文件,会导致文件指针移动
4.lseek
off_t lseek(int fd, off_t offset, int whence);
移动文件指针的位置。
whence的取值:
whence | 意义 |
SEEK_SET | 将读写位置指向文件头后再增加offset个位移量 |
SEEK_CUR | 以目前的读写位置往后增加offset个位移量 |
SEEK_END | 将读写位置指向文件尾部再增加offset个位移量 |
两个进程可以打开同一个文件进行操作,实现数据的共享。但是,当两个进程打开同一个文件进行写操作时,会相互覆盖。当文件被打开两次时,两个文件描述符有各自的文件指针。内核保存一个全局的文件描述符结构体,而一个文件打开两个之后,两个结构体各自有各自的文件指针。
6.文件映射
文件映射能将硬盘映射到进程的地址,这样可以像操作内存一样操作文件,效率高。但有一些限制:1.文件长度必须大于等于映射长度,2.映射的offset必须是页的整数倍。
获取页大小的方式:命令,getconf -a | grep PAGE_SIZE;函数,sysconf(_SC_PAGE_SIZE)。
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
*addr文件映射地址,为NULL时,系统自动分配;length映射长度;
prot取值:
PROT_EXEC:内存页可执行
PROT_READ:内存页可读
PROT_WRITE:内存页可写
PROT_NONE:内存页不可访问
flags取值:
MAP_SHARED:共享内存
MAP_PRIVATE:私有内存
fd:已打开文件的文件描述符;offset:文件开始映射的偏移量