void clearerr(FILE * stream);
相关函数 feof
函数说明 clearerr()清除参数stream指定的文件流所使用的错误旗标。
int fclose(FILE * stream);
相关函数 close,fflush,fopen,setbuf
函数说明 fclose()用来关闭先前fopen()打开的文件。此动作会让缓冲区内的数据写入文件中,并释放系统所提供的文件资源。
返回值 若关文件动作成功则返回0,有错误发生时则返回EOF并把错误代码存到errno。
错误代码 EBADF表示参数stream非已打开的文件。
范例 请参考fopen()。
FILE * fdopen(int fildes,const char * mode);
相关函数 fopen,open,fclose
函数说明 fdopen()会将参数fildes 的文件描述词,转换为对应的文件指针后返回。参数mode 字符串则代表着文件指针的流形态,此形态必须和原先文件描述词读写模式相同。关于mode 字符串格式请参考fopen()。
返回值 转换成功时返回指向该流的文件指针。失败则返回NULL,并把错误代码存在errno中。
int feof(FILE * stream);
相关函数 fopen,fgetc,fgets,fread
函数说明 feof()用来侦测是否读取到了文件尾,尾数stream为fopen()所返回之文件指针。如果已到文件尾则返回非零值,其他情况返回0。
返回值 返回非零值代表已到达文件尾。
int fflush(FILE* stream);
相关函数 write,fopen,fclose,setbuf
函数说明 fflush()会强迫将缓冲区内的数据写回参数stream指定的文件中。如果参数stream为NULL,fflush()会将所有打开的文件数据更新。
返回值 成功返回0,失败返回EOF,错误代码存于errno中。
错误代码 EBADF 参数stream 指定的文件未被打开,或打开状态为只读。其它错误代码参考write()。
int fgetc(FILE * stream);
相关函数 open,fread,fscanf,getc
函数说明 fgetc()从参数stream所指的文件中读取一个字符。若读到文件尾而无数据时便返回EOF。
返回值 getc()会返回读取到的字符,若返回EOF则表示到了文件尾。
char * fgets(char * s,int size,FILE * stream); (由文件中读取一字符串)
相关函数 open,fread,fscanf,getc
表头文件 include<stdio.h>
函数说明 fgets()用来从参数stream所指的文件内读入字符并存到参数s所指的内存空间,直到出现换行字符、读到文件尾或是已读了size-1个字符为止,最后会加上NULL作为字符串结束。
返回值 gets()若成功则返回s指针,返回NULL则表示有错误发生。
int fileno(FILE * stream); (返回文件流所使用的文件描述词)
相关函数 open,fopen
函数说明 fileno()用来取得参数stream指定的文件流所使用的文件描述词。
返回值 返回文件描述词。
FILE * fp;
int fd;
fp=fopen(“/etc/passwd”,”r”);
fd=fileno(fp);
printf(“fd=%d\n”,fd);
fclose(fp);
执行 fd=3
FILE * fopen(const char * path,const char * mode);(打开文件)
相关函数 open,fclose
函数说明 参数path字符串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态。
mode有下列几种形态字符串:
r 打开只读文件,该文件必须存在。
r+ 打开可读写的文件,该文件必须存在。
w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。
a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。
上 述的形态字符串都可以再加一个b字符,如rb、w+b或ab+等组合,加入b 字符用来告诉函数库打开的文件为二进制文件,而非纯文字文件。不过在POSIX系统,包含Linux都会忽略该字符。由fopen()所建立的新文件会具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)权限,此文件权限也会参考umask 值。
返回值 文件顺利打开后,指向该流的文件指针就会被返回。若果文件打开失败则返回NULL,并把错误代码存在errno 中。
附加说明 一般而言,开文件后会作一些文件读取或写入的动作,若开文件失败,接下来的读写动作也无法顺利进行,所以在fopen()后请作错误判断及处理。
int fputc(int c,FILE * stream); (将一指定字符写入文件流中)
相关函数 fopen,fwrite,fscanf,putc
函数说明 fputc 会将参数c 转为unsigned char 后写入参数stream 指定的文件中。
返回值 fputc()会返回写入成功的字符,即参数c。若返回EOF则代表写入失败。
int fputs(const char * s,FILE * stream); (将一指定的字符串写入文件内)
相关函数 fopen,fwrite,fscanf,fputc,putc
函数说明 fputs()用来将参数s所指的字符串写入到参数stream所指的文件内。
返回值 若成功则返回写出的字符个数,返回EOF则表示有错误发生。
范例 请参考fgets()。
size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream);(从文件流读取数据)
相关函数 fopen,fwrite,fseek,fscanf
定义函数
函 数说明 fread()用来从文件流中读取数据。参数stream为已打开的文件指针,参数ptr 指向欲存放读取进来的数据空间,读取的字符数以参数size*nmemb来决定。Fread()会返回实际读取到的nmemb数目,如果此值比参数 nmemb 来得小,则代表可能读到了文件尾或有错误发生,这时必须用feof()或ferror()来决定发生什么情况。
返回值 返回实际读取到的nmemb数目。
#define nmemb 3
struct test
{
char name[20];
int size;
}s[nmemb];
FILE * stream;
int i;
stream = fopen(“/tmp/fwrite”,”r”);
fread(s,sizeof(struct test),nmemb,stream);
fclose(stream);
for(i=0;i<nmemb;i++)
printf(“name[%d]=%-20s:size[%d]=%d\n”,i,s[i].name,i,s[i].size);
执行 name[0]=Linux! size[0]=6
name[1]=FreeBSD! size[1]=8
name[2]=Windows2000 size[2]=11
FILE * freopen(const char * path,const char * mode,FILE * stream); (打开文件)
相关函数 fopen,fclose
函数说明 参数path字符串包含欲打开的文件路径及文件名,参数mode请参考fopen()说明。参数stream为已打开的文件指针。Freopen()会将原stream所打开的文件流关闭,然后打开参数path的文件。
返回值 文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno 中。
int fseek(FILE * stream,long offset,int whence);(移动文件流的读写位置)
相关函数 rewind,ftell,fgetpos,fsetpos,lseek
函数说明 fseek()用来移动文件流的读写位置。参数stream为已打开的文件指针,参数offset为根据参数whence来移动读写位置的位移数。
参数 whence为下列其中一种:
SEEK_SET从距文件开头offset位移量为新的读写位置。SEEK_CUR 以目前的读写位置往后增加offset个位移量。
SEEK_END将读写位置指向文件尾后再增加offset个位移量。
当whence值为SEEK_CUR 或SEEK_END时,参数offset允许负值的出现。
下列是较特别的使用方式:
1) 欲将读写位置移动到文件开头时:fseek(FILE *stream,0,SEEK_SET);
2) 欲将读写位置移动到文件尾时:fseek(FILE *stream,0,0SEEK_END);
返回值 当调用成功时则返回0,若有错误则返回-1,errno会存放错误代码。
附加说明 fseek()不像lseek()会返回读写位置,因此必须使用ftell()来取得目前读写的位置。
FILE * stream;
long offset;
fpos_t pos;
stream=fopen(“/etc/passwd”,”r”);
fseek(stream,5,SEEK_SET);
printf(“offset=%d\n”,ftell(stream));
rewind(stream);
fgetpos(stream,&pos);
printf(“offset=%d\n”,pos);
pos=10;
fsetpos(stream,&pos);
printf(“offset = %d\n”,ftell(stream));
fclose(stream);
执行 offset = 5 offset =0 offset=10
long ftell(FILE * stream);(取得文件流的读取位置)
相关函数 fseek,rewind,fgetpos,fsetpos
定义函数
函数说明 ftell()用来取得文件流目前的读写位置。参数stream为已打开的文件指针。
返回值 当调用成功时则返回目前的读写位置,若有错误则返回-1,errno会存放错误代码。
错误代码 EBADF 参数stream无效或可移动读写位置的文件流。
范例 参考fseek()。
size_t fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream);(将数据写至文件流)
相关函数 fopen,fread,fseek,fscanf
函数说明 fwrite()用来将数据写入文件流中。参数stream为已打开的文件指针,参数ptr 指向欲写入的数据地址,总共写入的字符数以参数size*nmemb来决定。Fwrite()会返回实际写入的nmemb数目。
返回值 返回实际写入的nmemb数目。
int getc(FILE * stream); (由文件中读取一个字符)
相关函数 read,fopen,fread,fgetc
函数说明 getc()用来从参数stream所指的文件中读取一个字符。若读到文件尾而无数据时便返回EOF。虽然getc()与fgetc()作用相同,但getc()为宏定义,非真正的函数调用。
返回值 getc()会返回读取到的字符,若返回EOF则表示到了文件尾。
范例 参考fgetc()。
int getchar(void); (由标准输入设备内读进一字符)
相关函数 fopen,fread,fscanf,getc
函数说明 getchar()用来从标准输入设备中读取一个字符。然后将该字符从unsigned char转换成int后返回。
返回值 getchar()会返回读取到的字符,若返回EOF则表示有错误发生。
附加说明 getchar()非真正函数,而是getc(stdin)宏定义。
char * gets(char *s); (由标准输入设备内读进一字符串)
相关函数 fopen,fread,fscanf,fgets
函数说明 gets()用来从标准设备读入字符并存到参数s所指的内存空间,直到出现换行字符或读到文件尾为止,最后加上NULL作为字符串结束。
返回值 gets()若成功则返回s指针,返回NULL则表示有错误发生。
附加说明 由于gets()无法知道字符串s的大小,必须遇到换行字符或文件尾才会结束输入,因此容易造成缓冲溢出的安全性问题。建议使用fgets()取代。
范例 参考fgets()
char * mktemp(char * template); (产生唯一的临时文件名)
相关函数 tmpfile
表头文件 #include<stdlib.h>
函数说明 mktemp()用来产生唯一的临时文件名。参数template所指的文件名称字符串中最后六个字符必须是XXXXXX。产生后的文件名会借字符串指针返回。
返回值 文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno中。
附加说明 参数template所指的文件名称字符串必须声明为数组,如:
char template[ ]=”template-XXXXXX”;
不可用char * template=”template-XXXXXX”;
int putc(int c,FILE * stream); (将一指定字符写入文件中)
相关函数 fopen,fwrite,fscanf,fputc
函数说明 putc()会将参数c转为unsigned char后写入参数stream指定的文件中。虽然putc()与fputc()作用相同,但putc()为宏定义,非真正的函数调用。
返回值 putc()会返回写入成功的字符,即参数c。若返回EOF则代表写入失败。
范例 参考fputc()。
int putchar (int c); (将指定的字符写到标准输出设备)
相关函数 fopen,fwrite,fscanf,fputc
函数说明 putchar()用来将参数c字符写到标准输出设备。
返回值 putchar()会返回输出成功的字符,即参数c。若返回EOF则代表输出失败。
附加说明 putchar()非真正函数,而是putc(c,stdout)宏定义。
范例 参考getchar()。
void rewind(FILE * stream); (重设文件流的读写位置为文件开头)
相关函数 fseek,ftell,fgetpos,fsetpos
函数说明 rewind()用来把文件流的读写位置移至文件开头。参数stream为已打开的文件指针。此函数相当于调用fseek(stream,0,SEEK_SET)。
返回值
范例 参考fseek()
void setbuf(FILE * stream,char * buf); (设置文件流的缓冲区)
相关函数 setbuffer,setlinebuf,setvbuf
函 数说明 在打开文件流后,读取内容之前,调用setbuf()可以用来设置文件流的缓冲区。参数stream为指定的文件流,参数buf指向自定的缓冲区起始地 址。如果参数buf为NULL指针,则为无缓冲IO。Setbuf()相当于调 用:setvbuf(stream,buf,buf?_IOFBF:_IONBF,BUFSIZ)
返回值
void setbuffer(FILE * stream,char * buf,size_t size);(设置文件流的缓冲区)
相关函数 setlinebuf,setbuf,setvbuf
函数说明 在打开文件流后,读取内容之前,调用setbuffer()可用来设置文件流的缓冲区。参数stream为指定的文件流,参数buf指向自定的缓冲区起始地址,参数size为缓冲区大小。
返回值
相关函数 setbuffer,setbuf,setvbuf
函数说明 setlinebuf()用来设置文件流以换行为依据的无缓冲IO。相当于调用:setvbuf(stream,(char * )NULL,_IOLBF,0);请参考setvbuf()。
返回值
int setvbuf(FILE * stream,char * buf,int mode,size_t size); (设置文件流的缓冲区)
相关函数 setbuffer,setlinebuf,setbuf
函数说明 在打开文件流后,读取内容之前,调用setvbuf()可以用来设置文件流的缓冲区。参数stream为指定的文件流,参数buf指向自定的缓冲区起始地址,参数size为缓冲区大小,参数mode有下列几种
_IONBF 无缓冲IO
_IOLBF 以换行为依据的无缓冲IO
_IOFBF 完全无缓冲IO。如果参数buf为NULL指针,则为无缓冲IO。
返回值
int ungetc(int c,FILE * stream); (将指定字符写回文件流中)
相关函数 fputc,getchar,getc
函数说明 ungetc()将参数c字符写回参数stream所指定的文件流。这个写回的字符会由下一个读取文件流的函数取得。
返回值 成功则返回c 字符,若有错误则返回EOF。
//
int open( const char * pathname, int flags);
int open( const char * pathname,int flags, mode_t mode);
作用:以各种方式打开文件
返回值:返回打开的文件句柄,-1 打开失败
函数说明 参数pathname 指向欲打开的文件路径字符串,
既可以是相对路径也可以是绝对路径。flags
参数有一系列常数值可供选择,可以同时选择多个常数用按位或运算符连接起来,所以这些常数的宏定义都以O_
开头,表示or
下列是参数flags 所能使用的旗标:
必选项:以下三个常数中必须指定一个,且仅允许指定一个。
O_RDONLY 以只读方式打开文件
O_WRONLY 以只写方式打开文件
O_RDWR 以可读写方式打开文件。上述三种旗标是互斥的,也就是不可同时使用,但可与下列的旗标利用OR(|)运算符组合。
以下可选项可以同时指定0个或多个,和必选项按位或起来作为flags
参数。
O_CREAT 若欲打开的文件不存在则自动建立该文件。
O_EXCL 如果O_CREAT 也被设置,此指令会去检查文件是否存在。文件若不存在则建立该文件,否则将导致打开文件错误。此外,若O_CREAT与O_EXCL同时设置,并且欲打开的文件为符号连接,则会打开文件失败。
O_NOCTTY 如果欲打开的文件为终端机设备时,则不会将该终端机当成进程控制终端机。
O_TRUNC 若文件存在并且以可写的方式打开时,此旗标会令文件长度清为0,而原来存于该文件的资料也会消失。
O_APPEND 当读写文件时会从文件尾开始移动,也就是所写入的数据会以附加的方式加入到文件后面。
O_NONBLOCK 以不可阻断的方式打开文件,也就是无论有无数据读取或等待,都会立即返回进程之中。
O_NDELAY 同O_NONBLOCK。
O_SYNC 以同步的方式打开文件。
O_NOFOLLOW 如果参数pathname 所指的文件为一符号连接,则会令打开文件失败。
O_DIRECTORY 如果参数pathname 所指的文件并非为一目录,则会令打开文件失败。
此为Linux2.2以后特有的旗标,以避免一些系统安全问题。
第三个参数mode
指定文件权限,可以用八进制数表示,比如0644表示-rw-r--r--
,也可以用S_IRUSR
、S_IWUSR
等宏定义按位或起来表示,参数mode 则有下列数种组合,只有在建立新文件时才会生效,文件权限由open
的mode
参数和当前进程的umask
掩码共同决定,因此该文件权限应该为(mode-umaks)。
S_IRWXU00700 权限,代表该文件所有者具有可读、可写及可执行的权限。
S_IRUSR 或S_IREAD,00400权限,代表该文件所有者具有可读取的权限。
S_IWUSR 或S_IWRITE,00200 权限,代表该文件所有者具有可写入的权限。
S_IXUSR 或S_IEXEC,00100 权限,代表该文件所有者具有可执行的权限。
S_IRWXG 00070权限,代表该文件用户组具有可读、可写及可执行的权限。
S_IRGRP 00040 权限,代表该文件用户组具有可读的权限。
S_IWGRP 00020权限,代表该文件用户组具有可写入的权限。
S_IXGRP 00010 权限,代表该文件用户组具有可执行的权限。
S_IRWXO 00007权限,代表其他用户具有可读、可写及可执行的权限。
S_IROTH 00004 权限,代表其他用户具有可读的权限
S_IWOTH 00002权限,代表其他用户具有可写入的权限。
S_IXOTH 00001 权限,代表其他用户具有可执行的权限。
返回值 若所有欲核查的权限都通过了检查则返回0 值,表示成功,只要有一个权限被禁止则返回-1。
错误代码 EEXIST 参数pathname 所指的文件已存在,却使用了O_CREAT和O_EXCL旗标。
EACCESS 参数pathname所指的文件不符合所要求测试的权限。
EROFS 欲测试写入权限的文件存在于只读文件系统内。
EFAULT 参数pathname指针超出可存取内存空间。
EINVAL 参数mode 不正确。
ENAMETOOLONG 参数pathname太长。
ENOTDIR 参数pathname不是目录。
ENOMEM 核心内存不足。
ELOOP 参数pathname有过多符号连接问题。
///
大多数unix文件I/O只需要用到5个函数:open,read,write,lseek,close。这些函数都为不带缓存的I/O,不带缓存指的是每个read和write都调用内核中的一个系统调用。这些函数使用时要用到三个头文件:sys/types.h,sys/stat.h,fcntl.h
open函数:int
open(const char path *name, int oflag,...);
返回:若成功为只写打开的文件描述符,若错误为-1。
调用open函数可以打开或创建一个文件,仅当创建新文件时才使用第三个参数,由open函数返回的文件描述符一定是最小的未用的描述符数字。
第一个参数为路径名
第二个参数为文件状态标志:
O_RDONLY或0:可读
O_WRONLY或1:可写
O_RDWR或2:可执行
O_APPEND:每次写时都加到文件的尾部
O_CREAT:若此文件不存在则创建它,使用此选项时,需同时说明第三个参数mode,用其说明该新文件的存取许可权位
O_EXCL:如果同时指定了O_CREAT,而文件已经存在,则出错,这可测试一个文件是否存在,如果不存在则创建此文件成为一个原子操作
O_TRUNC:如果此文件存在,而且为只读或只写成功打开,则将其长度截短为0
O_NOCTTY:如果pathname指的是终端设备,则不将此设备分配作为此进程的控制终端
O_NONBLOCK:如果pathname指的是一个FIFO,一个块特殊文件或一个字符特殊文件,则此选择项为此文件的本次打开操作和后续的I/O操作设置非阻塞方式
O_SYNC:使每次write都等到物理I/O操作完成
第三个参数一般为文件权限:
S_IRWXU,0700:代表该文件所有者具有可读,可写,可指向的权限
S_IRUSR或S_IREAD,0400:代表该文件所有者具有可读取的权限
S_IWUSR或S_IWRITE,0200:代表该文件所有者具有可写入的权限
S_IXUSR或S_IEXEC,0100:代表该文件所有者具有可指向的权限
S_IRWXG,0070:代表该文件用户组具有可读,可写,可执行的权限
S_IRGRP,0040:代表该文件用户组具有可读的权限
S_IWGRP,0020:代表该文件用户组具有可写的权限
S_IXGRP,0010:代表该文件用户组具有可执行的权限
S_IRWXO,0007:代表其他用户具有可读,可写,可执行的权限
S_IROTH,0004:代表其他用户具有可读的权限
S_IWOTH,0002:代表其他用户具有可写的权限
S_IXOTH,0001:代表其他用户具有可执行的权限
creat函数:int
creat(const char *pathname, mode_t mode);
返回:若成功为只写打开的文件描述符,若出错为-1
该函数等效于:open(pathname,O_WRONLY|O_CREAT|O_TRUNC,mode);
用于创建一个新文件
read函数:ssize_t
read(int filedes, void *buff, size_t nbytes);
返回:读到的字节数,若已到文件尾为0,若出错为-1
有多种情况可使实际读到的字节数少于要求读字节数:
(1)读普通文件时,在读到要求字节数之前已到达了文件尾端,如,若在到达文件尾端之前还有
30个字节,而要求读100个字节,则read返回30,下一次在调用read时,它将返回0。
(2)当从终端设备读时,通常一次最多读一行
(3)当从网络读时,网络中的缓冲机构可能造成返回值小于所要求读的字节数。
(4)某些面向记录的设备,如磁带一次最多返回一个记录
读操作从文件的当前位移量处开始,在成功返回之前,该位移量增加实际读得的字节数
write函数:ssize_t
write(int filedes, const void *buff,size_t nbytes);
返回:若成功为已写的字节数,若出错为-1
close函数:int
close(int filedes);
返回:若成功为0,若出错为-1
关闭一个文件时也释放该进程加在该文件上的所有记录锁,当一个进程终止时,它所有的打开文件都由内核自动关闭。
lseek函数:off_t
lseek(int filedes, off_t offset, int whence);
返回:若成功为新的文件位移,若出错为-1
每个打开文件都有一个与其相关联的”当前文件位移量”,它是一个非负整数,用以度量从文件开始处计算的字节数。按系统默认,当打开一个文件时,除非指定O_APPEND选项时,否则该位移量被设置为0。通常读,写操作都从当前文件位移量处开始,并使位移量增加所读或写的字节数。可以调用lseek显式地定位一个打开的文件。
对参数offset的解释与参数whence的值有关。
若whence是SEEK_SET,则将该文件的位移量设置为距文件开始处offset个字节
若whence是SEEK_CUR,则将该文件的位移量设置为其当前值加offset,offset可为正或负
若whence是SEEK_END,则将该文件的位移量设置为文件长度加offset,offset可为正或负
早期用0,1,2代铁SEEK_SET,SEEK_CUR,SEEK_END。
某些设备也可能允许负的位移量,但对于普通文件,则其位移量必须是非负值
范例:
#include
#include
#include
#include
#include
int
main(void)
{
int
fd, size;
char
buf1[]="Hello, world";
char
buf2[50];
if((fd=open("/home/sam/helloworld",O_CREAT|O_TRUNC|O_RDWR,0666))==-1)
{
printf("Open
or create file named \"helloworld\" failed.\n");
exit(1);
}
write(fd,buf1,sizeof(buf1));
close(fd);
if((fd=open("/home/sam/helloworld",O_RDONLY))==-1)
{
printf("Open
file named \"helloworld\" failed.\n");
exit(1);
}
size=read(fd,buf2,sizeof(buf2));
close(fd);
printf("%s\n",buf2);
if((fd=open("/home/sam/helloworld",O_RDONLY))==-1)
{
printf("Open
file named \"helloworld\" failed.\n");
exit(1);
}
lseek(fd,6,SEEK_SET);
size=read(fd,buf2,sizeof(buf2));
printf("%s\n",buf2);
close(fd);
return
0;
}