1. 文件操作系统的调用
Linux的文件操作系统调用(在Windows编程领域,操作系统提供的接口称为 API)涉及创建(create)、打开(open)、读写(read/write)和关闭(close)文件。
1.1 创建
int creat(const char *filename, mode_t mode)
参数mode指定新建文件的存取属性, 它和umask一起决定了文件的最终权限(mode&umask),其中,umask代表了文件在创建时需要去掉的一些存取权限。umask可以通过系统调用umask()来改变:
int umask(int newmask);
该调用讲umask设置为newmask, 然后返回旧的umask, 它只会影响读、写和执行权限。
1.2 打开
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
open()函数有2个形式, pathname是要打开的文件名(需要包含路径名称,缺省是未当前路径)。flags是文件打开标志,可以是一个值或者几个值的组合
标志 | 含义 |
O_RDONLY | 只读方式 |
O_WRONLY | 只写方式 |
O_RDWR | 读写方式 |
O_APPEND | 追加的方式 |
O_CREAT | 创建一个文件 |
O_EXEC | 如果使用了O_CREAT而且文件已经存在,就会发生一个错误 |
O_NOBLOCK | 非阻塞的方式 |
O_TRUNC | 如果文件已经存在,则删除文件的内容 |
O_RDONLY、O_WRONLY、O_RDWR三个标志只能使用一个。
如果使用了O_CREAT标志, 那么使用的函数是int open(const char *pathname, int flags, mode_t mode);这个使用还要指定mode标志,用来表示文件的访问权限。mode可以是一下组合
标志 | 含义 |
S_IRUSR | 用户可以读 |
S_IWUSR | 用户可以写 |
S_IXUSR | 用户可以执行 |
S_IRWXU | 用户可以读、写、执行 |
S_IRGRP | 组可以读 |
S_IWGRP | 组可以写 |
S_IXGRP | 组可以执行 |
S_IRWXG | 组可以读、写、执行 |
S_IROTH | 其他人可以读 |
S_IWOTH | 其他人可以写 |
S_IXOTH | 其他人可以执行 |
S_IRWXO | 其他人可以读、写、执行 |
S_ISUID | 设置用户执行ID |
S_ISGID | 设置组的执行ID |
除了可以通过上述宏进行“或”逻辑产生标志以外,我们也可以自己用数字来表示,Linux用5个数字来表示文件的各种权限:第一位表示设置用户ID;第二位表示设置组ID;第三位表示用户自己的权限位;第四位表示组的权限;最后一位表示其他人的权限。每个数字可以取1(执行权限)、2(写权限)、4(读权限)、0(无)或者是 这些值的和。例如,要创建一个用户 可读、可写、可执行,但是组没有权限,其他人可以读、可以执行的文件、并设置用户ID位,那么应该使用的模式是1(设置用户ID)、0(不设置ID)、7(1+2+4,读、写、执行)、0(没有 权限)、5(1+4,读、执行)即10 705:
open(“file”, O_CREAT, 10705);
上述语句等价于:
open("file", O_CREAT, S_IRWXU | S_IROTH | S_IXOTH | S_ISUID);
如果文件打开成功, open函数会返回一个文件描述符, 以后对该文件的所有操作就可以通过对这个文件描述符进行操作就可以实现。
1.3 读写
在文件打开以后, 我们才可以对文件进行读写,Linux中提供文件读写的系统调用是read、write函数:
int read(int fd, const void *buf, size_t length);
int write(int fd, const void *buf, size_t length);
其中, 参数 buf 为指向缓冲区的指针, length 为缓冲区的大小(以字节为单位)。函数 read() 实现从文件描述符 fd 所指定的文件中读取 length 个字节到 buf 所指向的缓冲区中, 返回值为实际读取的字节数。 函数 write 实现把 length 个字节从 buf 指向的缓冲区中写入到 文件描述符 fd 所指向的文件中, 返回值为实际写入的字节数。
以O_CREAT 为标志的 open 实际上实现了文件创建的功能, 因此, 下面的函数等同于 creat() 函数:
int open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
1.4 定位
对于随机文件, 可以随机指定位置进行读写, 使用如下函数进行定位:
int lseek(int fd, offset_t offset, int whence);
lseek() 把文件读写指针相对 whence 移动 offset 个字节。 操作成功时, 返回文件指针相对于文件头的位置。 参数 whence 可以使用下属值:
SEEK_SET:相对文件开头
SEEK_CUR:相对文件读写指针的当前位置
SEEK_END:相对文件末尾
offset 可取负值, 例如下面调用可以把文件指针相对当前位置 向前移动5个字节:
lseek(fd, -5, SEEK_CUR);
由于 lseek 函数的返回值为文件指针相对于文件头的位置, 因此下面调用的返回值就是文件的长度:
lseek(fd, 0, SEEK_END);
1. 5 关闭
当我们操作完成以后, 要关闭文件,此时,只要调用close就可以了, 其中 fd 是要关闭的文件描述符:
int close(int fd);