一、打开/关闭文件
1
名称: | open |
目标: | 打开一个文件。 |
头文件: | #include <sys/types.h> #include <sys/stat.h> #include < fcntl.h> |
函数原形: | int open(const char * pathname,int flags); int open(const char * pathname,int flags,mode_t mode); |
参数: | pathname 文件名 |
| flags 打开模式 |
返回值: | -1 遇到错误 |
| int 打开成功,返回文件描述符。 |
这个系统调用在进程和文件之间建立一条连接 ,这个连接被称为文件描述符,它就像一条由进程通向内核的管道。
要打开一个文件,必须指定文件名和打开模式,有3种打开模式:只读,只写,可读可写,分别对应于O_RDONLY,O_WRONLY,O_RDWR,这在头文件/usr/include/fcntl.h中有定义。
打开文件是内核提供的服务,如果在打开过程中内核检测到任何错误,这个系统调用就会返回-1。错误的类型是各种各样的,如:要打开的文件不存在。即使文件存在可能因为权限不够而无法打开,在open的联机帮助中列出了各种可能的错误,大家可以看看。
UNIX允许一个文件被多个进程访问,也就是说当一个文件被一个进程打开后,这个文件还可以被其它进程打开。
如果文件被顺利打开内核会返回一个正整数的值,这个数值就叫文件描述符,文件描述符是是一个简单的整数,用以标明每一个被进程所打开的文件,描述符0代表标准输出,对应的宏是 STDOUT_FILENO,描述符1代表标准输入,对应的宏为STDIN_FILENO,描述符2代表标准错误输出,对应的宏为STDERR_FILENO,系统给进程分配描述符都是从3开始的,如果同时打开好几个文件,它们所对应的的文件描述符是不同的,如果一个文件打开多次,对应的文件描述符也不相同。必须通过文件描述符对文件操作。下面的程序可以证明这一点。
/*1_1.c*/ #include <stdio.h> #include <fcntl.h> #include <unistd.h>
int main(int ac,char *av[]) { int fd; int size; char buf[1024];
if(ac==1) printf(“please input file!/n”); else { while(--ac) { printf(“file:%s/n”,av[ac]); fd=open(av[ac],O_RDONLY); printf(“fd,%d/n”,fd); size=read(fd,buf,sizeof(buf)); printf(“fd,%d/n”,size); printf(“%s”,buf); } } close(fd); } |
我们编译一下 [root@LINUX root]# cc –o show_read show_read.c 运行 [root@LINUX root]# ./show_read show_read.c 下面是运行结果。 file: show_read.c fd:3 size:423 #include <stdio.h> ……
|
我们可以看出此次打开文件的文件描述符是3,如果我们执行下面的语句。
[root@LINUX root]# ./show_read show_read.c show_read.c 下面是运行结果: file: 3 size: 423 #include <stdio.h> ……
file: 4 size 432 #include <stdio.h> ……
|
可以看到,我们第一次打开文件的描述符是3,第二次打开文件的文件描述符是4。
Open 函数的第二个功能是创建一个新文件并把它打开,其中有几个宏定义对于着flags参数:
O_CREAT 如果打开文件不存在open就创建一个文件。
O_TRUNC 如果打开的文件已经存在open就把原文件清空,长度置为0。
所有我们利用open(pathname, O_WRONLY| O_CREAT| O_TRUNC,0777);
下面是一个例子
/*1_2.c*/ #include <unistd.h> #include <sys/stat.h> #include <sys/fcntl.h> #include <stdio.h>
char buf[]=”abcdefg”; int main(int argc,char *argv[ ]) { int fd; if((fd=open(argv[1],O_RDWR|O_CREAT|O_TRUNC,0777))==-1) perror (“error”); if(write(fd,buf,7)!=7) perror(“error”); if(read(fd,buf,sizeof(buf))<0) perror (“error”); printf(“%s/n”,buf);: } |
2.
名称: | close |
目标: | 关闭一个文件。 |
头文件: | #include < unistd.h> |
函数原形: | int close(int fd) |
参数: | fd 文件描述符 |
返回值: | -1 遇到错误 |
| int 关闭成功,返回文件描述符。 |
Close这个系统调用会关闭进程和文件fd之间的连接,如果关闭过程中出现错误,close返回-1,如:fd所指的文件并不存在。关闭成功则返回文件描述符。
3.
名称: | creat |
目标: | 创建/重写一个文件 |
头文件: | #include <sys/types.h> #include <stat.h> #include < fcntl.h> |
函数原形: | int creat(const char *pathname,mode_t mode) |
参数: | pathname 文件名 |
| mode 访问模式 |
返回值: | -1 遇到错误 |
/ | fd 创建成功,返回文件描述符 |
Creat告诉内核创建一个名为filename的文件,如果这个文件不存在,就创建它,如果已经存在,就把它的内容清空,把文件的长度设为0。
如果内核成功地创建了文件,那么文件的许可位(permission bits)被设置为由第二个参数mode所指定的值.如:
fd=creat(“addressbook”,0644);
创建一个名为addressbook的文件,如果文件不存在,那么文件的许可位被设为 rw-r-r—.
如果文件已存在它的内容会被清空。任一情况下,fd都会是指向addressbook的文件描述符。
二、文件的读取和写入
4.
名称: | read |
目标: | 把数据读到缓冲区。 |
头文件: | #include < unistd.h> |
函数原形: | ssize_t read(int fd, void *buf, size_t count) |
参数: | fd 文件描述符 |
| buf 用来存放数据的目的缓冲区 |
| count 要读取的字节数 |
返回值: | -1 遇到错误 |
| numread 成功关闭,返回所读取的字节数目。 |
read这个系统调用请求内核从fd所指定的文件中读取qty字节的数据,存放到buf所指定的内存空间中,内核如果成功地读取了数据,就返回所读取的字节数目。否则返回-1。
当文件的字节数没有你想要的那么多时,read就会判断下一个数值是不是’/0’,如果是就停止读取,然后退出。numread返回的是’/0’之前的字节数,也就是是原文件的字节数而不是你想读的字节数。
本文转自http://blog.chinaunix.net/u1/59291/showart.php?id=538534