unix环境下文件I/O函数

来源:互联网 发布:按网络的拓扑结构分类 编辑:程序博客网 时间:2024/05/20 08:24

1.符号描述符

首先要记住,对于所有打开的文件系统都是通过文件描述符来引用的。文件描述符是一个非负整数。在unix系统中(大部分系统也是这样),用0代表标准输入流,用1代表标准输出流,用2代表标准错误流。在头文件<unistd.h>中定义了STDIN_FILENO,STDOUT_FILENO以及STDERR_FILENO。


2.open函数

open函数可以打开或者创建一个文件,函数原型如下

#include <fcntl.h>int open(const char *pathname,int oflag,.../*mode_t mode*/)返回值:若成功返回文件描述符,若出错返回-1

pathname不用说指的是文件的路径名,注意使用'/'来间隔目录。

对于第二个参数oflag,以下是需要使用到fcntl.h中的常用参数:

O_RDONLY(只读)O_WRONLY(只写)O_RDWR(读写)//以上这三个常量只能选择一个O_APPEND(末尾追加)O_CREAT(如果文件不存在则创建文件,这时需要使用第三个参数mode,指定该文件的访问权限位)O_EXCL(如果文件存在,则出错,用来检测文件是否存在)O_TRUNC(如果文件存在,而且为只读或只写打开,则将其长度截短为1)

 对于open函数,当且仅当创建新文件时才使用的三个参数。由open返回的文件描述符一定是最小的未用的文件描述符,这可以用先关闭标准输出,然后打开文件,则文件的描述符为1。


3.creat函数

creat函数用来创建一个新文件,函数原型如下

#includ <fcntl.h>int creat(const *pathname,mode_t mode)返回值:若成功则返回为只写打开的文件描述符,否则返回-1等效于open(pathname.O_WRONLY | O_CREAT | O_TRUNC,mode)

由于creat只能以写的方式打开文件,要想读取该文件需要creat,close,open。可以直接采用如下方式open(pathname,O_RDWR | O_CREAT |O_TRUNC,mode)。


4.close函数

关闭文件并释放其所占资源,函数原型如下

#include<unistd.h>int close(int filedes)返回值:成功返回0,否则返回-1


5.lseek函数

每个打开的文件在内核中都维护了一个“当前文件偏移量”,指的是从文件开始处计算的字节数。除非使用O_APPEND,否则偏移量一般都为0。

调用lseek显示地为一个打开的文件设置偏移量,函数原型如下

#include <unistd.h>off_t lssek(int filedes, off_t offset, int whence)返回值:若成功则返回新的文件偏移量,若出错则返回-1//若whence为SEEK_SET,则将文件的偏移量设置为距文件开始处offset个字节。//////若whence为SEEK_CUR,则将文件的偏移量设置为当前值加offset,offset可正可负。//若whence为SEEK_END,,则将文件的偏移量设置为文件长度加offse,offset可正可负,//注意文件偏移量可以大于当前文件长度,系统并不会为之间的空洞分配磁盘空间,只为新的数据分配磁盘空间。


6.read函数

调用read函数从打开的文件中读取数据,函数原型如下:

#include <unistd.h>ssize_t read(int filedes,void *buf,size_t nbytes)返回值:若成功返回读到的字节数,若已到文件结尾则返回0,若出错返回-1

7.write函数

调用write函数向打开的文件写数据,函数原型如下:

#include <unistd.h>ssize_t write(int filedes,const void* buff,size_t nbytes)返回值:若成功返回已写的字节数,若出错返回-1
其返回值通常与参数nbytes相同,否则表示出错。常见的出错原因包括:磁盘已经写满、超过了文件的最大长度限制。对于普通文件,写操作从文件的当前偏移量处开始。执行一次成功的写之后,文件的偏移量增加实际写的字节数。


8.文件I/O函数总结

1).进程终止时,uinx系统内核会关闭该进程的所有打开的文件描述符,所以可以不用必须关闭输入和输出文件(最好还是自行关闭,以免造成内存资源的浪费)。

2).上述的open、creat、close、lseek、read、write都是系统内核函数,对文本文件和二进制文件没有区别。

3).用以下程序来实践一下。

#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <string.h>#define BUFFSIZE 2048int main(int argc,char **argv){int fd,num;char buf[BUFFSIZE];char *fileName = "./1.txt";off_t pos;// 在当前目录下以读写的方式打开文件,若文件不存在则创建文件 if(( fd = open(fileName,O_RDWR | O_CREAT | O_TRUNC)) < 0){printf("open file fail%s\n",fileName);exit(1);}//从键盘读入数据,再写入到文件中while((num = read(STDIN_FILENO,buf,BUFFSIZE)) > 0){//如果为"stop"则停止输入if(strncmp(buf,"stop",4)==0){printf("write data stop\n");break;}if(write(fd,buf,num) != num){printf("write data fail\n");exit(1);}printf("write data success\n");}//在文件最后的第10个字节出插入"?"if((pos = lseek(fd,-10,SEEK_END)) == -1){printf("lssek fail\n");exit(1);}if(write(fd,"?",1) != 1){printf("read fail\n");exit(1);}return 0;}
注意:这里的文件creat时没有设置权限,所以读取时要用到root权限。运行结果如下:(可以尝试把偏移量设置为10,运行下结果看看)