3.2文件描述符
对内核而言,所有打开的文件都通过文件描述符引用。文件描述符是一个非负整数。当打开一个现有文件或者创建一个新文件时,内核向进城返回一个文件描述符。当读或者写一个问一个文件时候,使用open或者create返回文件描述符标识该文件。将其作为参数传递给read或者write。
unix系统shell使用文件描述符0与进城的标准输入相关联。文件描述符1与标准输出有关联。文件描述符2与标准出错输出相关联。
#define 0 STDIN_FILENO
#define 1 STDOUT_FILENO
#define 2 STDERR_FILENO
文件描述符的范围0~OPEN_MAX,目前都将其增至63.
3.3open函数
调用open函数可以打开或者创建一个文件。
#include <fcntl.h>
int open(const char* pathname,int oflag,...);
...表示仅当创建新文件时候才使用第三个参数。
pathname 表示打开或者创建的文件名字 。oflag参数可用来说明此函数的多个选项。有如下常量 O_RDONLY(只读 0),O_WRONLY(只写1),O_RDWR(读写打开 2) 。 上述三个参数必须指定切只能指定一个
下边的参数是可选的。O_APPEND ,每次写的时候追加到尾端。O_CREATE,创建文件,但是mode要指定访问权限。O_EXCL,判断是否文件存在。。。。。还有许多参数请参考http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_1.html
同步输入输出:O_DSYNC ,O_RSYNC,O_SYNC
由open返回的文件描述符一定是最小的未使用的描述符数值。
3.4create函数
也可以调用create创建一个新文件。
#include<fcntl.h>
int create(const char* pathname,mode_t mode);
返回值,若成功,则返回为只写打开的文件描述符,若出错,则返回-1;
此函数相当于open(path那么,O_WRONLY|O_CREAT|O_TRUNC,mode);
3.5close 函数
#include<unistd.h>
int close(int fileds);
关闭文件,若成功返回0,不成功返回-1;
3.6lseek函数
每打开的文件都有一个与其相关连的“当前文件偏移量”,通常是非负整数。通常读写操作都是从偏移量开始的。系统默认情况下打开文件时,偏移量为0,当设置O_APPEND。
实例
#include "apue.h"
int main(void)
{
if(lseek(STDIN_FILENO,0,SEEK_CUR)==-1)
printf("cannot seek\n");
else
printf("seek ok\n");
exit(0);
}
运行结果
lseek 将当前文件的的偏移量记录在内核中,他并不引起任何I/O。然后该偏移量用户下一个读写操作。文件偏移量可以大于文件的当前长度,在这种情况下,对该文件的下一次系将加长该文件。并在文件中构成一个空洞。位于文件中并没有写过的字节都被度为0.
#include "apue.h"
#include "fcntl.h"
char buf1[]="abcdefghij";
char buf2[]="ABCDEFGHIJ";
int main(void)
{
int fd;
if(fd=creat("file.hole",FILE_MODE)<0)
err_sys("create error");
if(write(fd,buf1,10)!=10)
err_sys("buf1 write error");
if(lseek(fd,16384,SEEK_SET)==-1)
err_sys("lseek error");
if(write,(fd,buf2,10)!=10)
err_sys("lseek error");
exit(0);
}
运行结果
空洞文件是存在的。
3.7read 函数
调用read函数从打开的文件中读取数据。
#include<unistd.h>
ssize_t read(int filedes,void* buf,size_t nbytes);
若成功则返回读到的字节数,若以到文件结尾则返回0,若出错则返回-1;
经典定义:首先,void*表示通用指针
其次,返回值必须是带符号整数。ssize_t,已返回字节数,0,-1
第三个参数不带符号,这允许一个16为的实现一次读写数据大65534个字节。
3.8 write函数
调用write函数向打开的文件写数据
#include<unistd.h>
ssize_t write( int fileds,const void* buf,size_t nbytes);
成功返回已经写的字节,失败返回-1;
3.9 I/O效率
示例:将标准输入复制到标准输出
#include "apue.h"
#define BUFFSIZE 4096
int main(void)
{
int n;
char buf[BUFFSIZE];
while((n=read(STDIN_FILENO,buf ,BUFFSIZE))>0)
if(write(STDOUT_FILENO,buf,n)!=n)
err_sys("write error");
if(n<0)
err_sys("read error");
exit(0);
}
书中有对此程序的测试,BUFFSIZE 设置从1到524288,系统CPU时间最小为4096,当逐渐增大,时间又变长了,但变化很小。