这里讲的I/O操作都称为unbuffered I/O,主要是指在每次调用读写函数read和write的时候都会进入内核,因此与ISO C中的standard I/O区别。虽然称为unbuffered,但其实还是使用了缓冲区的。
文件描述符用来表示一个打开的文件,文件描述符是一个非负整数。一般程序中默认打开了的文件描述符为0:STDIN_FILENO,1:STDOUT_FILENO,2:STDERR_FILENO,它们定义在头文件中。
open函数:
- #include <fcntl.h>
-
int open(const char *pathname, int oflag,... /* mode_t mode */)
-
// returns: file descriptor if OK, -1 on error
上面只有当在创建文件时才会用到第三个参数mode_t mode。 这个函数返回的是一个文件描述符,而且该文件描述符是未使用的描述符中最小的那个。比如程序第一次调用open返回的值应该为3,因为默认的0,1,2已经使用了。
pathname指定要打开和创建的文件的路径和文件名。
oflag指定一些选项,其中O_RDONLY, O_WRONLY, O_RDWR三个中必须要指定其中一个。
其他的部分oflag选项如下(其余参阅man手册):
O_APPEND: 在文件末尾写,具有原子性(atomic)
O_CREAT: 文件不存在时创建文件,这时需要第三个参数mode来指定被创建文件的访问权限。
O_EXCL: 与O_CREAT结合使用,如果文件已存在,则会返回错误。
O_TRUNC:如果文件已存在并且成功打开用于写或读写,就会将文件大小截断为0.
creat函数:
- #include <fcntl.h>
-
int creat(const char *pathname, mode_t mode);
-
// Returns: file descriptor opened for write-only if OK, -1 on error
等价于调用:open(pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);
close函数:
- #include <unistd.h>
-
int close(int filedes);
-
// Returns: 0 if OK, -1 on error
关闭文件会释放该文件的所有的record locks, 进程结束时也会自动关闭所有打开的文件。注意:一个成功执行的close函数并不保证close之前的write操作已执行完。
lseek函数:
- #include <unistd.h>
-
off_t lseek(int filedes, off_t offset, int whence);
-
// Returns: new file offset if OK, -1 on error
每个打开的文件都有一个“current file offset”,通常为一个非负数。通常read和write操作都会改变这个offset。
函数里的三个参数,filedes指示文件描述符, 对offset值的解释取决于whence的取值。whence的取值有如下三种情况:
SEEK_SET:这时current file offset = offset
SEEK_CUR:这时current file offset = current file offset + offset, 这样offset可正可负。
SEEK_END:这时current file offset = 文件大小 + offset,即以文件尾为起点。
对于常规文件(regular file)current file offset的值必须为非负。
待续...
阅读(1501) | 评论(0) | 转发(1) |