易语言教程_易语言源码_易语言写挂_易语言论坛_看流星社区

 找回密码
 注册
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
赞助广告位 请点击这里联系站长 QQ20209081
赞助广告位 请点击这里联系站长 QQ20209081
赞助广告位 请点击这里联系站长 QQ20209081
查看: 109|回复: 0

文件操作小结

[复制链接]
发表于 2017-6-3 14:26:31 | 显示全部楼层 |阅读模式
文件操作
在编程的过程中,文件的操作是一个经常用到的问题,在VC++中,可以使用多种方法对文件操作,下面我就按以下几个部分对此作详细介绍,就是:1、基于C的文件操作;2、基于C++的文件操作;3、基于WINAPI的文件操作;4、基于MFC库的文件操作。5、Unix/Linux文件操作
一、基于C的文件操作
clearerr(清除文件流的错误旗标) 相关函数 feof表头文件 #include<stdio.h> 定义函数 void clearerr(FILE * stream); 函数说明 clearerr()清除参数stream指定的文件流所使用的错误旗标。 返回值   fclose(关闭文件) 相关函数 close,fflush,fopen,setbuf 表头文件 #include<stdio.h> 定义函数 int fclose(FILE * stream); 函数说明 fclose()用来关闭先前fopen()打开的文件。此动作会让缓冲区内的数据写入文件中,并释放系统所提供的文件资源。 返回值 若关文件动作成功则返回0,有错误发生时则返回EOF并把错误代码存到errno。 错误代码 EBADF表示参数stream非已打开的文件。 范例 请参考fopen()。  fdopen(将文件描述词转为文件指针) 相关函数 fopen,open,fclose 表头文件 #include<stdio.h> 定义函数 FILE * fdopen(int fildes,const char * mode); 函数说明 fdopen()会将参数fildes 的文件描述词,转换为对应的文件指针后返回。参数mode 字符串则代表着文件指针的流形态,此形态必须和原先文件描述词读写模式相同。关于mode 字符串格式请参考fopen()。 返回值 转换成功时返回指向该流的文件指针。失败则返回NULL,并把错误代码存在errno中。范例 #include<stdio.h>main(){FILE * fp =fdopen(0,&rdquo;w+&rdquo;);fprintf(fp,&rdquo;%s/n&rdquo;,&rdquo;hello!&rdquo;);fclose(fp);}执行 hello!feof(检查文件流是否读到了文件尾) 相关函数 fopen,fgetc,fgets,fread 表头文件 #include<stdio.h> 定义函数 int feof(FILE * stream); 函数说明 feof()用来侦测是否读取到了文件尾,尾数stream为fopen()所返回之文件指针。如果已到文件尾则返回非零值,其他情况返回0。 返回值 返回非零值代表已到达文件尾。  fflush(更新缓冲区) 相关函数 write,fopen,fclose,setbuf 表头文件 #include<stdio.h> 定义函数 int fflush(FILE* stream); 函数说明 fflush()会强迫将缓冲区内的数据写回参数stream指定的文件中。如果参数stream为NULL,fflush()会将所有打开的文件数据更新。 返回值 成功返回0,失败返回EOF,错误代码存于errno中。 错误代码 EBADF 参数stream 指定的文件未被打开,或打开状态为只读。其它错误代码参考write()。  fgetc(由文件中读取一个字符) 相关函数 open,fread,fscanf,getc 表头文件 include<stdio.h> 定义函数 nt fgetc(FILE * stream); 函数说明 fgetc()从参数stream所指的文件中读取一个字符。若读到文件尾而无数据时便返回EOF。 返回值 getc()会返回读取到的字符,若返回EOF则表示到了文件尾。 范例 #include<stdio.h>main(){FILE *fp;int c;fp=fopen(&ldquo;exist&rdquo;,&rdquo;r&rdquo;);while((c=fgetc(fp))!=EOF)printf(&ldquo;%c&rdquo;,c);fclose(fp);} fgets(由文件中读取一字符串) 相关函数 open,fread,fscanf,getc 表头文件 include<stdio.h> 定义函数 har * fgets(char * s,int size,FILE * stream); 函数说明 fgets()用来从参数stream所指的文件内读入字符并存到参数s所指的内存空间,直到出现换行字符、读到文件尾或是已读了size-1个字符为止,最后会加上NULL作为字符串结束。 返回值 gets()若成功则返回s指针,返回NULL则表示有错误发生。 范例 #include<stdio.h>main(){char s[80];fputs(fgets(s,80,stdin),stdout);}执行 this is a test /*输入*/this is a test /*输出*/  fileno(返回文件流所使用的文件描述词) 相关函数 open,fopen 表头文件 #include<stdio.h> 定义函数 int fileno(FILE * stream); 函数说明 fileno()用来取得参数stream指定的文件流所使用的文件描述词。 返回值 返回文件描述词。范例 #include<stdio.h>main(){FILE * fp;int fd;fp=fopen(&ldquo;/etc/passwd&rdquo;,&rdquo;r&rdquo;);fd=fileno(fp);printf(&ldquo;fd=%d/n&rdquo;,fd);fclose(fp);}执行 fd=3  fopen(打开文件) 相关函数 open,fclose 表头文件 #include<stdio.h> 定义函数 FILE * fopen(const char * path,const char * mode); 函数说明 参数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()后请作错误判断及处理。 范例 #include<stdio.h>main(){FILE * fp;fp=fopen(&ldquo;noexist&rdquo;,&rdquo;a+&rdquo;);if(fp= =NULL) return;fclose(fp);} fputc(将一指定字符写入文件流中) 相关函数 fopen,fwrite,fscanf,putc 表头文件 #include<stdio.h> 定义函数 int fputc(int c,FILE * stream); 函数说明 fputc 会将参数c 转为unsigned char 后写入参数stream 指定的文件中。 返回值 fputc()会返回写入成功的字符,即参数c。若返回EOF则代表写入失败。 范例 #include<stdio.h>main(){FILE * fp;char a[26]=&rdquo;abcdefghijklmnopqrstuvwxyz&rdquo;;int i;fp= fopen(&ldquo;noexist&rdquo;,&rdquo;w&rdquo;);for(i=0;i<26;i++)fputc(a[i],fp);fclose(fp);}fputs(将一指定的字符串写入文件内) 相关函数 fopen,fwrite,fscanf,fputc,putc 表头文件 #include<stdio.h> 定义函数 int fputs(const char * s,FILE * stream); 函数说明 fputs()用来将参数s所指的字符串写入到参数stream所指的文件内。 返回值 若成功则返回写出的字符个数,返回EOF则表示有错误发生。 范例 请参考fgets()。
fread(从文件流读取数据) 相关函数 fopen,fwrite,fseek,fscanf 表头文件 #include<stdio.h> 定义函数 size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream); 函数说明 fread()用来从文件流中读取数据。参数stream为已打开的文件指针,参数ptr 指向欲存放读取进来的数据空间,读取的字符数以参数size*nmemb来决定。Fread()会返回实际读取到的nmemb数目,如果此值比参数nmemb 来得小,则代表可能读到了文件尾或有错误发生,这时必须用feof()或ferror()来决定发生什么情况。返回值 返回实际读取到的nmemb数目。
附加说明 范例 #include<stdio.h>#define nmemb 3struct test{char name[20];int size;}s[nmemb];
main(){FILE * stream;int i;stream = fopen(&ldquo;/tmp/fwrite&rdquo;,&rdquo;r&rdquo;);fread(s,sizeof(struct test),nmemb,stream);fclose(stream);for(i=0;i<nmemb;i++)printf(&ldquo;name[%d]=%-20s:size[%d]=%d/n&rdquo;,i,s[i].name,i,s[i].size);}执行 name[0]=Linux! size[0]=6name[1]=FreeBSD! size[1]=8name[2]=Windows2000 size[2]=11 freopen(打开文件) 相关函数 fopen,fclose 表头文件 #include<stdio.h> 定义函数 FILE * freopen(const char * path,const char * mode,FILE * stream); 函数说明 参数path字符串包含欲打开的文件路径及文件名,参数mode请参考fopen()说明。参数stream为已打开的文件指针。Freopen()会将原stream所打开的文件流关闭,然后打开参数path的文件。 返回值 文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno 中。范例 #include<stdio.h>main(){FILE * fp;fp=fopen(&ldquo;/etc/passwd&rdquo;,&rdquo;r&rdquo;);fp=freopen(&ldquo;/etc/group&rdquo;,&rdquo;r&rdquo;,fp);fclose(fp);}fseek(移动文件流的读写位置) 相关函数 rewind,ftell,fgetpos,fsetpos,lseek 表头文件 #include<stdio.h> 定义函数 int fseek(FILE * stream,long offset,int whence); 函数说明 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()来取得目前读写的位置。范例 #include<stdio.h>main(){FILE * stream;long offset;fpos_t pos;stream=fopen(&ldquo;/etc/passwd&rdquo;,&rdquo;r&rdquo;);fseek(stream,5,SEEK_SET);printf(&ldquo;offset=%d/n&rdquo;,ftell(stream));rewind(stream);fgetpos(stream,&amp;pos);printf(&ldquo;offset=%d/n&rdquo;,pos);pos=10;fsetpos(stream,&amp;pos);printf(&ldquo;offset = %d/n&rdquo;,ftell(stream));fclose(stream);}执行 offset = 5offset =0offset=10  ftell(取得文件流的读取位置) 相关函数 fseek,rewind,fgetpos,fsetpos 表头文件 #include<stdio.h> 定义函数 long ftell(FILE * stream); 函数说明 ftell()用来取得文件流目前的读写位置。参数stream为已打开的文件指针。 返回值 当调用成功时则返回目前的读写位置,若有错误则返回-1,errno会存放错误代码。 错误代码 EBADF 参数stream无效或可移动读写位置的文件流。范例 参考fseek()。  fwrite(将数据写至文件流) 相关函数 fopen,fread,fseek,fscanf 表头文件 #include<stdio.h> 定义函数 size_t fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream); 函数说明 fwrite()用来将数据写入文件流中。参数stream为已打开的文件指针,参数ptr 指向欲写入的数据地址,总共写入的字符数以参数size*nmemb来决定。Fwrite()会返回实际写入的nmemb数目。 返回值 返回实际写入的nmemb数目。范例 #include<stdio.h>#define set_s (x,y) {strcoy(s[x].name,y);s[x].size=strlen(y);}#define nmemb 3struct test{char name[20];int size;}s[nmemb];main(){FILE * stream;set_s(0,&rdquo;Linux!&rdquo;);set_s(1,&rdquo;FreeBSD!&rdquo;);set_s(2,&rdquo;Windows2000.&rdquo;);stream=fopen(&ldquo;/tmp/fwrite&rdquo;,&rdquo;w&rdquo;);fwrite(s,sizeof(struct test),nmemb,stream);fclose(stream);}执行 参考fread()。  getc(由文件中读取一个字符) 相关函数 read,fopen,fread,fgetc 表头文件 #include<stdio.h> 定义函数 int getc(FILE * stream); 函数说明 getc()用来从参数stream所指的文件中读取一个字符。若读到文件尾而无数据时便返回EOF。虽然getc()与fgetc()作用相同,但getc()为宏定义,非真正的函数调用。 返回值 getc()会返回读取到的字符,若返回EOF则表示到了文件尾。 范例 参考fgetc()。  getchar(由标准输入设备内读进一字符) 相关函数 fopen,fread,fscanf,getc 表头文件 #include<stdio.h> 定义函数 int getchar(void); 函数说明 getchar()用来从标准输入设备中读取一个字符。然后将该字符从unsigned char转换成int后返回。 返回值 getchar()会返回读取到的字符,若返回EOF则表示有错误发生。 附加说明 getchar()非真正函数,而是getc(stdin)宏定义。范例 #include<stdio.h>main(){FILE * fp;int c,i;for(i=0li<5;i++){c=getchar();putchar(c);}}执行 1234 /*输入*/1234 /*输出*/gets(由标准输入设备内读进一字符串) 相关函数 fopen,fread,fscanf,fgets 表头文件 #include<stdio.h> 定义函数 char * gets(char *s); 函数说明 gets()用来从标准设备读入字符并存到参数s所指的内存空间,直到出现换行字符或读到文件尾为止,最后加上NULL作为字符串结束。 返回值 gets()若成功则返回s指针,返回NULL则表示有错误发生。 附加说明 由于gets()无法知道字符串s的大小,必须遇到换行字符或文件尾才会结束输入,因此容易造成缓冲溢出的安全性问题。建议使用fgets()取代。 范例 参考fgets()  mktemp(产生唯一的临时文件名) 相关函数 tmpfile 表头文件 #include<stdlib.h> 定义函数 char * mktemp(char * template); 函数说明 mktemp()用来产生唯一的临时文件名。参数template所指的文件名称字符串中最后六个字符必须是XXXXXX。产生后的文件名会借字符串指针返回。 返回值 文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno中。附加说明 参数template所指的文件名称字符串必须声明为数组,如:char template[ ]=&rdquo;template-XXXXXX&rdquo;;不可用char * template=&rdquo;template-XXXXXX&rdquo;;范例 #include<stdlib.h>main(){char template[ ]=&rdquo;template-XXXXXX&rdquo;;mktemp(template);printf(&ldquo;template=%s/n&rdquo;,template);} putc(将一指定字符写入文件中) 相关函数 fopen,fwrite,fscanf,fputc 表头文件 #include<stdio.h> 定义函数 int putc(int c,FILE * stream); 函数说明 putc()会将参数c转为unsigned char后写入参数stream指定的文件中。虽然putc()与fputc()作用相同,但putc()为宏定义,非真正的函数调用。 返回值 putc()会返回写入成功的字符,即参数c。若返回EOF则代表写入失败。 范例 参考fputc()。  putchar(将指定的字符写到标准输出设备) 相关函数 fopen,fwrite,fscanf,fputc 表头文件 #include<stdio.h> 定义函数 int putchar (int c); 函数说明 putchar()用来将参数c字符写到标准输出设备。 返回值 putchar()会返回输出成功的字符,即参数c。若返回EOF则代表输出失败。 附加说明 putchar()非真正函数,而是putc(c,stdout)宏定义。 范例 参考getchar()。 rewind(重设文件流的读写位置为文件开头) 相关函数 fseek,ftell,fgetpos,fsetpos 表头文件 #include<stdio.h> 定义函数 void rewind(FILE * stream); 函数说明 rewind()用来把文件流的读写位置移至文件开头。参数stream为已打开的文件指针。此函数相当于调用fseek(stream,0,SEEK_SET)。返回值 范例 参考fseek()
setbuf(设置文件流的缓冲区) 相关函数 setbuffer,setlinebuf,setvbuf 表头文件 #include<stdio.h> 定义函数 void setbuf(FILE * stream,char * buf); 函数说明 在打开文件流后,读取内容之前,调用setbuf()可以用来设置文件流的缓冲区。参数stream为指定的文件流,参数buf指向自定的缓冲区起始地址。如果参数buf为NULL指针,则为无缓冲IO。Setbuf()相当于调用:setvbuf(stream,buf,buf?_IOFBF:_IONBF,BUFSIZ) 返回值   setbuffer(设置文件流的缓冲区) 相关函数 setlinebuf,setbuf,setvbuf 表头文件 #include<stdio.h> 定义函数 void setbuffer(FILE * stream,char * buf,size_t size); 函数说明 在打开文件流后,读取内容之前,调用setbuffer()可用来设置文件流的缓冲区。参数stream为指定的文件流,参数buf指向自定的缓冲区起始地址,参数size为缓冲区大小。 返回值
setlinebuf(设置文件流为线性缓冲区) 相关函数 setbuffer,setbuf,setvbuf 表头文件 #include<stdio.h> 定义函数 void setlinebuf(FILE * stream); 函数说明 setlinebuf()用来设置文件流以换行为依据的无缓冲IO。相当于调用:setvbuf(stream,(char * )NULL,_IOLBF,0);请参考setvbuf()。 返回值 setvbuf(设置文件流的缓冲区) 相关函数 setbuffer,setlinebuf,setbuf 表头文件 #include<stdio.h> 定义函数 int setvbuf(FILE * stream,char * buf,int mode,size_t size); 函数说明 在打开文件流后,读取内容之前,调用setvbuf()可以用来设置文件流的缓冲区。参数stream为指定的文件流,参数buf指向自定的缓冲区起始地址,参数size为缓冲区大小,参数mode有下列几种_IONBF 无缓冲IO_IOLBF 以换行为依据的无缓冲IO_IOFBF 完全无缓冲IO。如果参数buf为NULL指针,则为无缓冲IO。 返回值 ungetc(将指定字符写回文件流中) 相关函数 fputc,getchar,getc 表头文件 #include<stdio.h> 定义函数 int ungetc(int c,FILE * stream); 函数说明 ungetc()将参数c字符写回参数stream所指定的文件流。这个写回的字符会由下一个读取文件流的函数取得。 返回值 成功则返回c 字符,若有错误则返回EOF。

二、基于C++的文件操作
在C++中,有一个stream这个类,所有的I/O都以这个&ldquo;流&rdquo;类为基础的,包括我们要认识的文件I/O,stream这个类有两个重要的运算符:1、插入器(<<)  向流输出数据。比如说系统有一个默认的标准输出流(cout),一般情况下就是指的显示器,所以,cout<<"Write Stdout"<<'/n';就表示把字符串"Write Stdout"和换行字符('/n')输出到标准输出流。2、析取器(>>)  从流中输入数据。比如说系统有一个默认的标准输入流(cin),一般情况下就是指的键盘,所以,cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据。  在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。下面就把此类的文件操作过程一一道来。1、打开文件  在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是:void open(const char* filename,int mode,int access);参数:filename:  要打开的文件名mode:    要打开文件的方式access:   打开文件的属性打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下:ios::app:   以追加的方式打开文件ios::ate:   文件打开后定位到文件尾,ios:app就包含有此属性ios::binary:  以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文ios::in:    文件以输入方式打开ios:ut:   文件以输出方式打开ios::nocreate: 不建立文件,所以文件不存在时打开失败 ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败ios::trunc:  如果文件存在,把文件长度设为0  可以用&ldquo;或&rdquo;把以上属性连接起来,如ios:ut|ios::binary  打开文件的属性取值是:0:普通文件,打开访问1:只读文件2:隐含文件4:系统文件  可以用&ldquo;或&rdquo;或者&ldquo;+&rdquo;把以上属性连接起来 ,如3或1|2就是以只读和隐含属性打开文件。  例如:以二进制输入方式打开文件c:/config.sys  fstream file1;  file1.open("c://config.sys",ios::binary|ios::in,0);  如果open函数只有文件名一个参数,则是以读/写普通文件打开,即:  file1.open("c://config.sys");<=>file1.open("c://config.sys",ios::in|ios:ut,0);  另外,fstream还有和open()一样的构造函数,对于上例,在定义的时侯就可以打开文件了:  fstream file1("c://config.sys");  特别提出的是,fstream有两个子类:ifstream(input file stream)和ofstream(outpu file stream),ifstream默认以输入方式打开文件,而ofstream默认以输出方式打开文件。  ifstream file2("c://pdos.def");//以输入方式打开文件  ofstream file3("c://x.123");//以输出方式打开文件  所以,在实际应用中,根据需要的不同,选择不同的类来定义:如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定义。2、关闭文件  打开的文件使用完成后一定要关闭,fstream提供了成员函数close()来完成此操作,如:file1.close();就把file1相连的文件关闭。3、读写文件  读写文件分为文本文件和二进制文件的读取,对于文本文件的读取比较简单,用插入器和析取器就可以了;而对于二进制的读取就要复杂些,下要就详细的介绍这两种方式  1)、文本文件的读写  文本文件的读写很简单:用插入器(<<)向文件输出;用析取器(>>)从文件输入。假设file1是以输入方式打开,file2以输出打开。示例如下:  file2<<"I Love You";//向文件写入字符串"I Love You"  int i;  file1>>i;//从文件输入一个整数值。  这种方式还有一种简单的格式化能力,比如可以指定输出为16进制等等,具体的格式有以下一些操纵符 功能 输入/输出dec 格式化为十进制数值数据 输入和输出endl 输出一个换行符并刷新此流 输出ends 输出一个空字符 输出hex 格式化为十六进制数值数据 输入和输出oct 格式化为八进制数值数据 输入和输出setpxecision(int p) 设置浮点数的精度位数 输出  比如要把123当作十六进制输出:file1<<hex<<123;要把3.1415926以5位精度输出:file1<<setpxecision(5)<<3.1415926。  2)、二进制文件的读写①put()  put()函数向流写入一个字符,其原型是ofstream &amp;put(char ch),使用也比较简单,如file1.put('c');就是向流写一个字符'c'。②get()  get()函数比较灵活,有3种常用的重载形式:  一种就是和put()对应的形式:ifstream &amp;get(char &amp;ch);功能是从流中读取一个字符,结果保存在引用ch中,如果到文件尾,返回空字符。如file2.get(x);表示从文件中读取一个字符,并把读取的字符保存在x中。  另一种重载形式的原型是: int get();这种形式是从流中返回一个字符,如果到达文件尾,返回EOF,如x=file2.get();和上例功能是一样的。  还有一种形式的原型是:ifstream &amp;get(char *buf,int num,char delim='/n');这种形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim指定的字符,如果没使用 delim 这个参数,将使用缺省值换行符'/n'。例如:  file2.get(str1,127,'A');//从文件中读取字符到字符串str1,当遇到字符'A'或读取了127个字符时终止。③读写数据块  要读写二进制数据块,使用成员函数read()和write()成员函数,它们原型如下:    read(unsigned char *buf,int num);    write(const unsigned char *buf,int num);  read()从文件中读取 num 个字符到 buf 指向的缓存中,如果在还未读入 num 个字符时就到了文件尾,可以用成员函数 int gcount();来取得实际读取的字符数;而write() 从buf 指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是unsigned char *,有时可能需要类型转换。例:    unsigned char str1[]="I Love You";    int n[5];    ifstream in("xxx.xxx");    ofstream out("yyy.yyy");    out.write(str1,strlen(str1));//把字符串str1全部写到yyy.yyy中    in.read((unsigned char*)n,sizeof(n));//从xxx.xxx中读取指定个整数,注意类型转换    in.close();out.close();4、检测EOF  成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int eof();例:  if(in.eof())ShowMessage("已经到达文件尾!");5、文件定位  和C的文件操作方式不同的是,C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时,相应的指针自动变化。所以,C++的文件定位分为读位置和写位置的定位,对应的成员函数是 seekg()和 seekp(),seekg()是设置读位置,seekp是设置写位置。它们最通用的形式如下:    istream &amp;seekg(streamoff offset,seek_dir origin);    ostream &amp;seekp(streamoff offset,seek_dir origin);  streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值,seek_dir 表示移动的基准位置,是一个有以下值的枚举:ios::beg:  文件开头ios::cur:  文件当前位置ios::end:  文件结尾  这两个函数一般用于二进制文件,因为文本文件会因为系统对字符的解释而可能与预想的值不同。例:     file1.seekg(1234,ios::cur);//把文件的读指针从当前位置向后移1234个字节     file2.seekp(1234,ios::beg);//把文件的写指针从文件开头向后移1234个字节

三、基于WINAPI的文件操作
在VC中,大多数情况对文件的操作都使用系统提供的 API 函数,以下提供一些文件操作 API 函数介绍:
1、一般文件操作 APICreateFile打开文件函数CreateFile可打开和创建文件、管道、邮槽、通信服务、设备以及控制台,但是在此时只是介绍用这个函数怎么实现创建和打开一个文件。





HANDLE CreateFile( LPCTSTR lpFileName, // 要打开的文件名 DWORD dwDesiredAccess, // 文件的操作属性 DWORD dwShareMode, // 文件共享属性  LPSECURITY_ATTRIBUTES lpSecurityAttributes,// 文件安全特性 DWORD dwCreationDisposition, //文件操作 DWORD dwFlagsAndAttributes, // 文件属性 HANDLE hTemplateFile // 如果不为零,则指定一个文件句柄。新文件将从这个文件中复制扩展属性 );





  文件的操作属性:如果为零,表示只允许获取与一个设备有关的信息,GENERIC_READ 表示允许对设备进行读访问;如果为 GENERIC_WRITE 表示允许对设备进行写访问(可组合使用);  文件的共享属性:零表示不共享; FILE_SHARE_READ 或 FILE_SHARE_WRITE 表示允许对文件进行读/写共享访问;  文件的操作有:  &middot;CREATE_NEW:创建文件;如文件存在则会出错  &middot;CREATE_ALWAYS:创建文件,会改写前一个文件  &middot;OPEN_EXISTING:文件必须已经存在。 由设备提出要求
&middot;OPEN_ALWAYS:如文件不存在则创建它  &middot;TRUNCATE_EXISTING:将现有文件缩短为零长度  文件属性有:  &middot;FILE_ATTRIBUTE_ARCHIVE:标记归档属性  &middot;FILE_ATTRIBUTE_COMPRESSED:将文件标记为已压缩,或者标记为文件在目录中的默认压缩方式  &middot;FILE_ATTRIBUTE_NORMAL:默认属性  &middot;FILE_ATTRIBUTE_HIDDEN:隐藏文件或目录  &middot;FILE_ATTRIBUTE_READONLY:文件为只读  &middot;FILE_ATTRIBUTE_SYSTEM:文件为系统文件  &middot;FILE_FLAG_WRITE_THROUGH:操作系统不得推迟对文件的写操作  &middot;FILE_FLAG_OVERLAPPED:允许对文件进行重叠操作  &middot;FILE_FLAG_NO_BUFFERING:禁止对文件进行缓冲处理。文件只能写入磁盘卷的扇区块  &middot;FILE_FLAG_RANDOM_ACCESS:针对随机访问对文件缓冲进行优化  &middot;FILE_FLAG_SEQUENTIAL_SCAN:针对连续访问对文件缓冲进行优化  &middot;FILE_FLAG_DELETE_ON_CLOSE:关闭了上一次打开的句柄后,将文件删除。特别适合临时文件  可以组合的属性有:FILE_FLAG_WRITE_THROUGH,FILE_FLAG_OVERLAPPED,FILE_FLAG_NO_BUFFERING,FILE_FLAG_RANDOM_ACCESS,FILE_FLAG_SEQUENTIAL_SCAN,FILE_FLAG_DELETE_ON_CLOSE,FILE_FLAG_BACKUP_SEMANTICS,FILE_FLAG_POSIX_SEMANTICS,FILE_FLAG_OPEN_REPARSE_POINT,FILE_FLAG_OPEN_NO_RECALL  如果成功返回一个打开文件得句柄,如果调用函数之前文件存在,文件操作属性为:CREATE_ALWAYS 或 OPEN_ALWAYS,使用GetLastError函数返回的是ERROR_ALREADY_EXISTS(包括函数操作成功),如果之前函数不存在,则返回0。使用失败返回INVALID_HANDLE_VALUE,要取得更多的信息,使用GetLastError函数。
ReadFile从文件中读取字节信息。 在打开文件获得了文件句柄之后,则可以通过该函数读取数据。BOOL ReadFile( HANDLE hFile, //文件的句柄 LPVOID lpBuffer, //用于保存读入数据的一个缓冲区 DWORD nNumberOfBytesToRead, //要读入的字符数 LPDWORD lpNumberOfBytesRead, //从文件中实际读入的字符数 LPOVERLAPPED lpOverlapped //如文件打开时指定了FILE_FLAG_OVERLAPPED,那么必须,用这个参数引用一个特殊的结构。该结构定义了一次异步读取操作。否则,应将这个参数设为NULL);
WriteFile 向文件写入字节信息。 同样可以将文件句柄传给该函数,从而实现对文件数据的写入。BOOL WriteFile( HANDLE hFile, //文件的句柄 LPCVOID lpBuffer, //要写入的一个数据缓冲区 DWORD nNumberOfBytesToWrite, //要写入数据的字节数量。如写入零字节,表示什么都不写入,但会更新文件的"上一次修改时间"。 LPDWORD lpNumberOfBytesWritten, //实际写入文件的字节数量 LPOVERLAPPED lpOverlapped // OVERLAPPED,倘若在指FILE_FLAG_OVERLAPPED的前提下打开文件,这个参数就必须引用一个特殊的结构。该结构定义了一次异步写操作。否则,该参数应置为NULL);
CloseHandle 关闭文件句柄。 打开门之后,自然要记得关上。GetFileTime 获取文件时间。 有三个文件时间可供获取:创建时间、最后访问时间、最后写时间。 该函数同样需要文件句柄作为入口参数。GetFileSize 获取文件大小。 由于文件大小可以高达上数G(1G需要30位),因此一个32位的双字节类型无法对其精确表达,因此返回码表示低32位,还有一个出口参数可以传出高32位。 该函数同样需要文件句柄作为入口参数。GetStatus得到文件状态。





static BOOL PASCAL GetStatus( LPCTSTR lpszFileName, CFileStatus&amp; rStatus );static void SetStatus( LPCTSTR lpszFileName, const CFileStatus&amp; status );throw( CFileException );





  返回的是一个CfileStatus对象,这个结构的具体的成员变量包括:





struct CFileStatus{ CTime m_ctime; // 文件创建时间 CTime m_mtime; // 文件最近一次修改时间 CTime m_atime; // 文件最近一次访问时间 LONG m_size; // 文件大小 BYTE m_attribute; // 文件属性 BYTE _m_padding; // 没有实际含义,用来增加一个字节 TCHAR m_szFullName[_MAX_PATH]; //绝对路径 #ifdef _DEBUG  //实现Dump虚拟函数,输出文件属性  void Dump(CDumpContext&amp; dc) const; #endif};





  下面就举一个例子来实现:





CFileStatus status;char *path = "D://VSS";if(CFile::GetStatus( path, status )){ CString cTime,mTime,aTime; cTime = status.m_ctime.Format("文件建立时间:%Y年%m月%d日 %H时%M分%S秒"); mTime = status.m_mtime.Format("文件最近修改时间:%Y年%m月%d日 %H时%M分%S秒"); aTime = status.m_atime.Format("文件最近访问时间:%Y年%m月%d日 %H时%M分%S秒"); CString str; str = cTime + "/n" + mTime +"/n" + aTime ; MessageBox(str);}





GetFileAttributes 获取文件属性。 可以获取文件的存档、只读、系统、隐藏等属性。 该函数只需一个文件路径作为参数。SetFileAttributes 设置文件属性。 能获取,自然也应该能设置。 可以设置文件的存档、只读、系统、隐藏等属性。 该函数只需一个文件路径作为参数。GetFileInformationByHandle 获取所有文件信息 该函数能够获取上面所有函数所能够获取的信息,如大小、属性等,同时还包括一些其他地方无法获取的信息,比如:文件卷标、索引和链接信息。 该函数需要文件句柄作为入口参数。GetFullPathName 获取文件路径,该函数获取文件的完整路径名。需要提醒的是:只有当该文件在当前目录下,结果才正确。如果要得到真正的路径。应该用GetModuleFileName函数。CopyFile 复制文件 注意:只能复制文件,而不能复制目录MoveFileEx 移动文件 既可以移动文件,也可以移动目录,但不能跨越盘符。(Window2000下设置移动标志可以实现跨越盘符操作)DeleteFile 删除文件GetTempPath 获取Windows临时目录路径GetTempFileName 在Windows临时目录路径下创建一个唯一的临时文件SetFilePoint 移动文件指针。 该函数用于对文件进行高级读写操作时。定位文件中的数据是很重要的,这决定了写入的数据在文件中的位置。API函数





DWORD SetFilePointer( HANDLE hFile, //文件的句柄 LONG lDistanceToMove, //字节偏移量r PLONG lpDistanceToMoveHigh, //指定一个长整数变量,其中包含了要使用的一个高双字偏移(一般用来操作大型文件)。可设为零,表示只使用lDistanceToMove  DWORD dwMoveMethod //文件定位);





  dwMoveMethod文件定位的方式有三种:  &middot;FILE_BEGIN:从文件开始处。  &middot;FILE_CURRENT:从当前位置。  &middot;FILE_END:从文件的末尾。  此函数可以用来定位大型文件,lpDistanceToMoveHigh是高32位,lDistanceToMove是低32位。如果lpDistanceToMoveHigh为NULL时,函数操作成功,返回的是当前文件数据的偏移量,如果lpDistanceToMoveHigh不NULL,则返回数据的偏移量高32位放在 lpDistanceToMoveHigh中,函数调用失败返回的是0xffffffff.2、文件的锁定和解锁LockFile UnlockFile LockFileEx UnlockFileEx 以上四个函数用于对文件进行锁定和解锁。这样可以实现文件的异步操作。可同时对文件的不同部分进行各自的操作。3、文件的压缩和解压缩LZOpenFile 打开压缩文件以读取LZSeek 查找压缩文件中的一个位置LZRead 读一个压缩文件LZClose 关闭一个压缩文件LZCopy 复制压缩文件并在处理过程中展开GetExpandedName 从压缩文件中返回文件名称。以上六个函数为32位 API 中的一个小扩展库,文件压缩扩展库中的函数。文件压缩可以用命令 compress 创建。4、文件内核对象 32位 API 提供一个称为文件映像的特性,它允许将文件直接映射为一个应用的虚拟内存空间,这一技术可用于简化和加速文件访问。CreateFileMapping 创建和命名映射MapViewOfFile 把文件映射装载如内存UnmapViewOfFile 释放视图并把变化写回文件FlushViewOfFile 将视图的变化刷新写入磁盘

四、基于MFC库的文件操作
1.文件的查找  当对一个文件操作时,如果不知道该文件是否存在,就要首先进行查找。MFC中有一个专门用来进行文件查找的类CFileFind,使用它可以方便快捷地进行文件的查找。下面这段代码演示了这个类的最基本使用方法。  CString strFileTitle;  CFileFind finder;  BOOL bWorking = finder.FindFile("C://windows//sysbkup//*.cab");  while(bWorking)  {  bWorking=finder.FindNextFile();  strFileTitle=finder.GetFileTitle();  }  2.文件的打开/保存对话框  让用户选择文件进行打开和存储操作时,就要用到文件打开/保存对话框。MFC的类CFileDialog用于实现这种功能。使用CFileDialog声明一个对象时,第一个BOOL型参数用于指定文件的打开或保存,当为TRUE时将构造一个文件打开对话框,为FALSE时构造一个文件保存对话框。  在构造CFileDialog对象时,如果在参数中指定了OFN_ALLOWMULTISELECT风格,则在此对话框中可以进行多选操作。此时要重点注意为此CFileDialog对象的m_ofn.lpstrFile分配一块内存,用于存储多选操作所返回的所有文件路径名,如果不进行分配或分配的内存过小就会导致操作失败。下面这段程序演示了文件打开对话框的使用方法。  CFileDialog mFileDlg(TRUE,NULL,NULL,---  OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT,  "All Files (*.*)|*.*||",AfxGetMainWnd());  CString str(" ",10000);  mFileDlg.m_ofn.lpstrFile=str.GetBuffer(10000);  str.ReleaseBuffer();  POSITION mPos=mFileDlg.GetStartPosition();  CString pathName(" ",128);  CFileStatus status;  while(mPos!=NULL)  {  pathName=mFileDlg.GetNextPathName(mPos);  CFile::GetStatus( pathName, status );  }  3.文件的读写  文件的读写非常重要,下面将重点进行介绍。文件读写的最普通的方法是直接使用CFile进行,如文件的创建打开读写可以使用下面的方法:
CFile创建和打开一个文件:  创建文件和打开文件的方法有很多种,下面简单介绍下几个构造函数:





CFile( LPCTSTR lpszFileName, UINT nOpenFlags );throw( CFileException );CFile( );BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL );





  lpszFileName:文件名称,可以是相对路径,绝对路径或网络路径  nOpenFlags:打开方式有:  &middot;CFile::modeCreate 调用构造函数构造一个新文件,如果文件已存在,则长度变成0。  &middot;CFile::modeNoTruncate 此值与modeCreate组合使用。如果所创建的文件已存在则其长度不变为0。因而此文件被打开,或者作为一个新文件或者作为一个已存在的文件。这将是很有用的,例如当打开一个可能存在也可能不存在的文件时。  &middot;CFile::modeRead 打开文件仅供读。  &middot;CFile::modeReadWrite 打开文件供读写。  &middot;CFile::modeWrite 打开文件仅供写。  &middot;CFile::modeNoInherit 阻止文件被子进程继承。  &middot;CFile::ShareDenyNone 不禁止其它进程读或写访问,打开文件。如果文件已被其它进程以兼容模式打开,则Create失败。  &middot;CFile::ShareDenyRead 打开文件,禁止其它进程读此文件。如果文件已被其它进程以兼容模式打开,或被其它进程读,则Create失败。  &middot;CFile::ShareDenyWrite 打开文件,禁止其它进程写此文件。如果文件已被其它进程以兼容模式打开,或被其它进程写,则Create失败。  &middot;CFile::ShareExclusive 以独占模式打开文件,禁止其它进程对文件的读写。如果文件已经以其它模式打开读写(即使被当前进程),则构造失败。  &middot;CFile::ShareCompat 此标志在32位MFC中无效。此标志在使用CFile:: Open时映射为CFile::ShareExclusive。  &middot;CFile::typeText 对回车换行设置特殊进程(仅用于派生类)。  &middot;CFile::typeBinary 设置二进制模式(仅用于派生类)。  下面给出MSDN中的一个例子:





char* pFileName = "test.dat";TRY{ CFile f( pFileName, CFile::modeCreate | CFile::modeWrite );}CATCH( CFileException, e ){ #ifdef _DEBUG  afxDump << "File could not be opened " << e->m_cause << "/n"; #endif}END_CATCH CFile fileTest;char* pFileName = "test.dat";TRY{ fileTest.Open(pFileName, CFile::modeCreate |CFile::modeWrite);}CATCH_ALL(e){ fileTest.Abort( ); THROW_LAST ( );}END_CATCH_ALL





//对文件进行读操作
//读取数据
UINT Read (void* lpBuf,UINT nCount); throw(CFileException);// 返回值是传输到缓冲区的字节数。
//写入数据
void Write(const void* lpBuf,UINT nCount);throw (CFileException);  char sRead[2];  CFile mFile(_T("user.txt"),CFile::modeRead);  if(mFile.GetLength()<2)  return;  mFile.Read(sRead,2);  mFile.Close();  //对文件进行写操作  CFile mFile(_T("user.txt "), CFile::modeWrite|CFile::modeCreate);  mFile.Write(sRead,2);  mFile.Flush();  mFile.Close();  虽然这种方法最为基本,但是它的使用繁琐,而且功能非常简单。我向你推荐的是使用CArchive,它的使用方法简单且功能十分强大。首先还是用CFile声明一个对象,然后用这个对象的指针做参数声明一个CArchive对象,你就可以非常方便地存储各种复杂的数据类型了。它的使用方法见下例。  //对文件进行写操作  CString strTemp="test";  CFile mFile;  mFile.Open("d://dd//try.TRY",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);  CArchive ar(&amp;mFile,CArchive::store);  ar<<strTemp;
  ar.Close();  mFile.Close();  //对文件进行读操作  CFile mFile;  if(mFile.Open("d://dd//try.TRY",CFile::modeRead)==0)  return;  CArchive ar(&amp;mFile,CArchive::load);   ar>>strTemp;  ar.Close();  mFile.Close();  CArchive的 << 和>> 操作符用于简单数据类型的读写,对于CObject派生类的对象的存取要使用ReadObject()和WriteObject()。使用CArchive的ReadClass()和WriteClass()还可以进行类的读写,如:  //存储CAboutDlg类  ar.WriteClass(RUNTIME_CLASS(CAboutDlg));  //读取CAboutDlg类  CRuntimeClass* mRunClass=ar.ReadClass();  //使用CAboutDlg类  CObject* pObject=mRunClass->CreateObject();  ((CDialog* )pObject)->DoModal();  虽然VC提供的文档/视结构中的文档也可进行这些操作,但是不容易理解、使用和管理,因此虽然很多VC入门的书上花费大量篇幅讲述文档/视结构,但我建议你最好不要使用它的文档。关于如何进行文档/视的分离有很多书介绍,包括非常著名的《Visual C++ 技术内幕》。  如果你要进行的文件操作只是简单的读写整行的字符串,我建议你使用CStdioFile,用它来进行此类操作非常方便,如下例。  CStdioFile mFile;  CFileException mExcept;  mFile.Open( "d://temp//aa.bat", CFile::modeWrite, &amp;mExcept);  CString string="I am a string.";  mFile.WriteString(string);  mFile.Close();
// 注:CStdioFile写入UNICODE字符时,必须指定文件类型为UNICODE,或者在文件头写入0XFFFE。 4.临时文件的使用
正规软件经常用到临时文件,你经常可以会看到C:/Windows/Temp目录下有大量的扩展名为tmp的文件,这些就是程序运行是建立的临时文件。临时文件的使用方法基本与常规文件一样,只是文件名应该调用函数GetTempFileName()获得。它的第一个参数是建立此临时文件的路径,第二个参数是建立临时文件名的前缀,第四个参数用于得到建立的临时文件名。得到此临时文件名以后,你就可以用它来建立并操作文件了,如:  char szTempPath[_MAX_PATH],szTempfile[_MAX_PATH];  GetTempPath(_MAX_PATH, szTempPath);  GetTempFileName(szTempPath,_T ("my_"),0,szTempfile);  CFile m_tempFile(szTempfile,CFile:: modeCreate|CFile:: modeWrite);  char m_char='a';  m_tempFile.Write(&amp;m_char,2);  m_tempFile.Close();

5.获取文件名,文件类型,文件长度,文件路径
用利用CFile打开一个文件时,可以在利用成员函数





virtual CString GetFileName( ) const, virtual CString GetFileTitle( ) const, virtual CString GetFilePath( ) const, virtual DWORD GetLength( ) const;throw( CFileException );





  来取得相关信息,如果一个文件的全路经是: c:/windows/write/myfile.wri,则每个函数取得的是: myfile.wri, myfile, c:/windows/write/myfile.wri. GetLength取得文件大小是按字节为单位的。  也可以利用:





virtual void SetLength( DWORD dwNewLen );throw( CFileException );virtual void SetFilePath( LPCTSTR lpszNewName );





  来设置文件的长度和路径。  在当前的文件下面新建一个Text.txt文件,在里面写点东西,然后运行下面程序:





CFile file("Text.txt",CFile::modeReadWrite);ULONGLONG length;CString strFilePath;length = file.GetLength();length = length + 1024*10;file.SetLength(length);file.SetFilePath("D://Text.txt");strFilePath = file.GetFilePath();MessageBox(strFilePath);file.Close();





  最后发现文件的路径变了,但是在D盘下面并没有找到Text.txt,原因是SetFilePath只能指定一个路径给文件,SetFilePath并不能做为移动文件来使用。CFile并没有给出取得文件类型的函数,但可以利用API来实现。
  5.文件的复制、删除等  MFC中没有提供直接进行这些操作的功能,因而要使用SDK。SDK中的文件相关函数常用的有CopyFile()、CreateDirectory()、DeleteFile()、MoveFile()。它们的用法很简单,可参考MSDN。

五、Unix/Linux文件操作
关于Unix/Linux文件操作参考http://dev.csdn.net/article/49/49776.shtm
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|看流星社区  |网站地图

GMT+8, 2017-10-24 19:09 易语言论坛 易语言导航

Powered by 看流星社区 X3.2

©2011-2016 最好的辅助编程技术论坛

快速回复 返回顶部 返回列表