Back

APUE reading notes-3

Fri, Aug 18 20171 min read
avatar
Nathaniel

第三章

本章主要讲了文件的I/O操作
Unix下主要有五个系统API接口用于操控文件,分别是openreadwritelseekclose,顾名思义,分别是用于打开、读取、写入、内部定位、关闭文件。

文件描述符

File Descriptors通常为一个非负整数,可以用于表示任何类型的文件(文件夹也是一种特殊的文件),操作系统的文件操作API通常以文件描述符作为参数。

参数选项

头文件<fcntl.h>中定义了一些常量,用作下面这些函数的参数,第一类参数选项为读写方式的选择,这些选项是互斥的
| 名称 | 意义 | | -------- | ---------- | | O_RDONLY | 只读模式 | | O_WRONLY | 只写模式 | | O_RDWR | 读写模式 | | O_EXEC | 仅执行模式 | | O_SEARCH | 仅搜索模式 |
第二类选项则为随意选择,由于数量众多,再次仅选一部分介绍
| 名称 | 意义 | | ----------- | ------------------------------------------ | | O_APPEND | 在文件末尾追加 | | O_CLOEXEC | 设定“在多线程调用时不重复打开该文件”的FLAG | | O_CREAT | 如果文件不存在则创建文件 | | O_DIRECTORY | 指定目标为目录,非目录则报错 | | O_EXCL | 创建文件时如果文件已经存在则报错 | | O_NOFOLLOW | 如果指向符号链接则报错 |

打开文件

open函数和openat函数
#include <fcntl.h>
int open(const char *path, int oflag, ... /* mode_t mode */ );
int openat(int fd, const char *path, int oflag, ... /* mode_t mode */ );
Open函数即为最基本的打开文件函数,在早期的Unix版本中仅仅用于打开文件,后来随着Unix版本演进,拥有了许多其他的功能。
这里简单解释一下上述两个函数的区别:
open函数为基础的打开文件函数,可用于任何类型的文件,功能也正如其名,打开文件,然后你就可以对文件进行各种操作了。
Openat函数解决了open函数所不能解决的一个问题,那就是在多线程的情况下,在对一个文件进行open的同时,该文件所在的目录可能被其他的线程或进程修改,而如果使用openat函数的话,该目录会被锁定,这样系统API调用者就不用每次都检测该目录是否存在了。

创建文件

creat函数
#include <fcntl.h>
int creat(const char *path, mode_t mode);
早起的Unix系统下的open函数仅仅具备打开文件的功能,因此,一个单独的creat系统调用就显得十分必要,因为有了这个函数才能创建新的文件,而后来随着Unix系统的发展,creat的功能和指定了O_WRONLY|O_CREAT|O_TRUNCopen函数有这相同的功能。

关闭文件

#include <unistd.h>
int close(int fd);
关闭文件的实质就是释放文件上所加的锁,释放了锁之后,其他的程序便可以对该文件进行相应的读写操作了。

文件内部定位

#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
每个文件都有一个当前文件偏移量,它通常来说是一个非负整数,用于表明当前j进行操作文件中的具体位置。使用 lseek可以把处理位置移动到指定的偏移量处。在调用lseek函数时可以使用一些FLAG,SEEK_SET表示移动到文件头+offset值的位置, SEEK_CUR表示移动到当前偏移量+offset值的位置, SEEK_END表示移动到文件末尾+offset值的位置。对于后两个FLAG,offset的值可以为负。
另外,lseek函数仅仅可以被用在普通文件上,对于管道、FIFO(命名的管道)、socket,则不能使用lseek

Comments(0)

Continue with
to comment