Unix系统中大多数文件I/O只需用到五个函数:open、read、write、lseek、close。本章说介绍的I/O是不带缓冲的,即:每个read和write都调用内核中的一个系统调用。不是ISO C的组成部分。对于内核而言,所有打开的文件都通过文件描述符引用。
在<unistd.h>中定义三个标准的文件描述符:
STDIN_FILENO 标准输入
STDOUT_FILENO 标准输出
STDERR_FILENO 标准出错输出
具体函数描述:在<fcntl.h>头文件下
int open(const char *path, int oflag, ... ); //打开或者创建一个文件
int creat(const char *path, mode_t mode); //创建一个文件int close(int fildes);//关闭一个打开的文件off_t lseek(int fildes, off_t offset, int whence); //为打开的文件设置偏移量ssize_t read(int fd, void *buf, size_t count);ssize_t write(int fildes, const void *buf, size_t nbyte);1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 8 int main() 9 {10 char *filename = ".//file";11 char buf[100];12 int fd;13 memset(buf,0,100);14 printf("Open file to write\n");15 //打开文件,不存在和新建16 if((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC,S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)17 {18 perror("Cannot open file\n");19 exit(1);20 }21 printf("Open file successfully.\n");22 printf("Input a string: ");23 gets(buf);24 //写入文件25 write(fd,buf,strlen(buf));26 close(fd);27 printf("Open file to read.\n");28 if((fd = open(filename, O_RDONLY)) == -1)29 {30 perror("Cannot open file\n");31 exit(1);32 }33 //从文件中读取34 read(fd,buf,100);35 printf("Read from file is: %s\n",buf);36 close(fd);37 return 0;38 }
程序测试结果如下:
复制一个现有的文件描述符函数
int dup(int fildes);int dup2(int fildes, int fildes2);dup返回的新文件描述符是当前可用文件描述符中最小值,dup2则是用fildes2参数指定新文件描述符的数值,若fildes2打开则关闭,若fildes等于fildes2则不关闭,返回fildes2.在CGI程序用dup2将文件描述符重新定位到标准输入和标准输出。即:dup2(fd,STDOUT_FILENO)或dup2(fd,STDIN_FILENO)。改变已打开文件的性质函数:int fcntl(int fd, int cmd, ... /* arg */ );函数功能:复制一个现有的描述符(cmd=F_DUPFD)获得或设置文件描述符(cmd=F_GETFD|F_SETFD)获得或设置文件状态标志(cmd=F_GETFL|F_SETFL)获得或设置异步I/O所有权(cmd=F_GETOWN|F_SETOWN)获得或设置记录锁(cmd=F_GETLK|F_SETLK、F_SETLKW)
可以用fcntl函数设置文件状态,常用设置套接字描述符为非阻塞O_NONBLOCK
下面写个程序完成打印出指定文件描述符的文件状态标志。程序如下:
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 8 int main(int argc,char* argv[]) 9 {10 int val;11 if(argc != 2)12 {13 printf("usage: \n");14 exit(-1);15 }16 val = fcntl(atoi(argv[1]),F_GETFL,0);17 if(val == -1)18 {19 perror("fcntl() error");20 exit(-1);21 }22 switch(val & O_ACCMODE)23 {24 case O_RDONLY:25 printf("read only.\n");26 break;27 case O_WRONLY:28 printf("write only\n");29 break;30 case O_RDWR:31 printf("read write.\n");32 break;33 default:34 printf("unknown access mode");35 }36 if(val&O_APPEND)37 printf(",append");38 if(val&O_NONBLOCK)39 printf(",nonblocking");\40 putchar('\n');41 return 0;42 }
程序测试结果如下: