文件描述符:
对于内核而言。所有打开的文件都通过文件描述符引用。文件描述符是一个非负整数。当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符。当读或写一个文件时,使用open或creat返回的文件描述符标示该文件,将其作为参数传给read或write。
按照惯例,UNIX系统shell使用文件描述符0与进程的标准输入相关,文件描述符1与标准输入出相关,文件描述符2与标准错误输出相关。
(当我们编写一个程序,在执行它时,默认会有三个文件描述符0,1,2,这三个文件描述符都指向当前的终端。这样,我们用0,1,2文件描述符进行read和write时都是相对于终端来进行的。用1进行write时将会把输入的内容输入到终端中)
open函数
调用open函数可以打开或创建一个文件。
#include<fcntl.h>
intopen(const char * pathname, int flag ,/*mode_t mode */);
对于open函数而言,仅当创建新文件时才使用第三个参数。在函数原型中将此参数放置在注视中。
constchar * pathname:
pathname是要打开或创建文件的名字(路径+文件名)。
intflag:
flag参数可用来说明此函数的多个选择。用下列一个或多个常量进行“或”运算构成flag参数。
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 读写打开
上述三个标志必须制定一个且只能制定一个
可选标志:
O_APPEND 每次写时都追加到文件的末尾
O_CREAT 若文件不存在,则创建文件,使用此选项时,需要第三个参数mode,用其制定该新文件的访问权限位(后面讲)
O_TRUNC 如果此文将存在,而且为只写或读写成功打开,则将其长度截短为0
creat函数
也可调用creat函数创建一个新文件。
#include<fcntl.h>
int creat(const char * pathname,mode_tmode);
返回值:若成功则返回为只写打开的文件描述符,若出错则返回-1
注意:此函数等效于:
open(pathname,O_WRONLY | O_CREAT |O_TRUNC ,mode);
close函数:
可调用close函数关闭一个打开的文件
#include<unistd.h>
int close(int filedes)
返回值:若成功返回0,若出错则返回-1
关闭一个文件时还会释放该进程加在该文件上的所有记录锁。
当一个进程终止时,内核自动关闭它所有打开的文件。很多程序都利用了这一功能而不显式地用close关闭文件。
lseek函数:
每个打开的文件都有一个与其相关的“当前文件偏移量”。它通常是一个非负整数,用
以量度从文件开始处计算的字节数。通常,读、写操作都从当前文件偏移量处开始,并使偏
移量增加所读写的字节数。按系统默认的情况,当打开一个文件时,除非指定O_APPEND
选项,否则该偏移量被设置为0。
可以调用lseek显式地为一个打开的文件设置其偏移量。
#include<unistd.h>
off_t lseek(intfiledes,off_t offset,int whence);
返回值:若成功则返回新文件的文件偏移量,若出错则返回-1
对参数offset的解释与参数whence的值有关。
1) 若whence是SEEK_SET,则该文件的偏移量设置为距文件开始处offset个字节,offset可为正负值。
2) 若whence是SEEK_CUR,则该文件的偏移量设置为其当前值加offset,offset可为正负值。
3) 若whence是SEEK_END,则将该文件的偏移量设置为文件的长度加offset,offset可为正负值。
若lseek成功执行,则返回新的文件偏移量,为此可以用下列方式确定打开文件的当前偏移量:
off_t currpos;
currpos =lseek(fd,0,SEEK_CUR);
read函数:
调用read函数从打开文件中读取数据。
#include<unistd.h>
ssize_t read(int filedes,void * buf,size_tnbytes);
返回值:若成功返回读到的字节数,若已到文件结尾则返回0,若出错则返回-1
write函数:
调用write函数向打开的文件写数据。
#include<unistd.h>
ssize_t write(int filedes,const void *buf,size_t nbytes);
返回值:若成功则返回已写入的字节数,若出错则返回-1
对于普通文件,写操作从文件的当前偏移量处开始,如果在打开文件时,制定了O_APPEND选项,则每次写操作之前,将文件偏移量设置在文件的当前结尾处,在一次成功写入后,该文件偏移量增加实际写的字节数。
程序实例:
1) 将标准输入复制到标准输出
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#define BUFFSIZE 4096
void main()
{
int n;
charbuf[BUFFSIZE];
while((n=read(0,buf,BUFFSIZE))>0) //从终端中读取内容
{
if(n<0)
{
printf(“read error”);
exit(0);
}
printf(“bytes:%d\n”,n);
if(write(1,buf,n)!=n) //写入终端
printf(“write error”);
}
}
//建议,读取缓冲区应设为4096字节,这样读写的效率高
2) 将一个已有的文件的内容复制到另一个文件中
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#define BUFFSIZE 4096
void main()
{
intfd1,fd2,n;
charbuf[BUFFSIZE];
if((fd1=open(“demo1.txt”,O_RDONLY,NULL))<0)
{
printf(“openread file error”);
exit(0);
}
if((fd2=open(“demo2.txt”,O_WRONLY,NULL))<0)
{
printf(“openwrite file error”);
exit(0);
}
while((n=read(fd1,buf,BUFFSIZE))!=0)
{
if(n<0)
{
printf(“read file error”);
close(fd1);
close(fd2);
exit(0);
}
if(n==0)
{
printf(“read end”);
close(fd1);
close(fd2);
exit(0);
}
if(write(fd2,buf,n)!=n)
{
printf(“writefile error”);
close(fd1);
close(fd2);
exit(0);
}
}
close(fd1);
close(fd2);
}