Unix系统编程文件I/O基础知识

文件描述符

对于内核而言,所有打开的文件都通过文件描述符引用,文件描述符是一个非负整数,当打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符,当读、写一个文件时,使用open或create返回的文件描述符标识该文件,将其传递给read或write。

按照惯例,UNIX系统shell把文件描述符0与进程的标准输入关联,文件描述符1与标准输出关联,文件描述符2与标准错误关联。在符合POSIX.1的应用程序中,幻数0、 1 、2已被标准化,通常把他们替换成符号常量:STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO,这样可以提高可读性,常定义在<unistd.h>中。

#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*/);

两个函数的返回值:若成功返回文件描述符,若出错,返回-1

path参数是要打开或创建的文件名字,oflag参数可用来说明此函数的多个选项,用下列一个或多个常量进行“或”运算构成oflag参数(这些常量在头文件<fcnttl.h>)中定义:

函数lseek

每个打开的文件都有一个与其相关联的“当前文件偏移量(current file offset)”,它通常是一个非负整数,用以度量从文件开始处计算的字节数,通常读、写操作都从当前偏移量处开始,并使偏移量增加所读写的字节数,按照系统默认设定,当打开一个文件时,除非指定O_APPEND选项,否则该偏移量被设置为0,可以调用lseek显示地为一个打开文件设置偏移量

#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);

若成功,返回新的文件偏移量,若出错,返回-1。

对参数offset的解释与参数whence相关。

1、若whence是SEEK_SET(0),则将该文件的偏移量设置为距文件开始处offset个字节。

2、若whence是SEEK_CUR(1),则将该文件的偏移量设置为其当前值加offset,offset可正可负。

3、若whence是SEEK_END(2),则将该文件的偏移量设置为文件长度加offset,offset可正可负。

若lseek执行成功,则返回新的文件偏移量,为此可以使用下列方式确定打开文件的当前偏移量:

off_t currpos;

currpos = lseek(fd, 0, SEEK_CUR);

这种方式也可以用来确定所涉及的文件是否可以设置偏移量。如果文件描述符指向的是一个管道、FIFO或网络套接字,则lseek返回-1,并将errno设置为ESPIPE。

关于文件偏移量大于文件长度的说明:如果文件偏移量大于文件的长度,对该文件的下一次写,将加长该文件,并在文件中构成一个空洞,这一点是允许的,位于文件中但没有写过的字节都被读为0。

文件中的空洞并不要求在磁盘上占用存储区。具体处理方式与文件系统的实现有关,当定位到超出文件尾端之后写时,对于新写的数据需要分配磁盘块,但是对于源文件尾端和新开始写位置之间的部分(空洞部分)则不需要分配磁盘块。

猜你喜欢

转载自blog.csdn.net/hello_java_Android/article/details/90487690