C++Builder⽂件操作⼤全
C++Builder⽂件操作⼤全
在编程的过程中,⽂件的操作是⼀个经常⽤到的问题,在C++Builder中,可以使⽤多种⽅法对⽂件操作,下⾯我就按以下⼏个部分对此作详细介绍,就是:
1、基于C的⽂件操作;
2、基于C++的⽂件操作;
3、基于WINAPI的⽂件操作;
4、基于BCB库的⽂件操作;
5、特殊⽂件的操作。
壹、基于C的⽂件操作
在ANSI C中,对⽂件的操作分为两种⽅式,即流式⽂件操作和I/O⽂件操作,下⾯就分别介绍之。
⼀、流式⽂件操作
这种⽅式的⽂件操作有⼀个重要的结构FILE,FILE在stdio.h中定义如下:
typedef struct {
int level; /* fill/empty level of buffer */
unsigned flags; /* File status flags */
char fd; /* File descriptor */
unsigned char hold; /* Ungetc char if no buffer */
int bsize; /* Buffer size */
unsigned char _FAR *buffer; /* Data transfer buffer */
unsigned char _FAR *curp; /* Current active pointer */
unsigned istemp; /* Temporary file indicator */
short token; /* Used for validity checking */
} FILE; /* This is the FILE object */
FILE这个结构包含了⽂件操作的基本属性,对⽂件的操作都要通过这个结构的指针来进⾏,此种⽂件操作常⽤的函数见下表 函数 功能 fopen() 打开流
fclose() 关闭流
fputc() 写⼀个字符到流中
fgetc() 从流中读⼀个字符
fseek() 在流中定位到指定的字符
fputs() 写字符串到流
fgets() 从流中读⼀⾏或指定个字符
fprintf() 按格式输出到流
fscanf() 从流中按格式读取
feof() 到达⽂件尾时返回真值
ferror() 发⽣错误时返回其值
rewind() 复位⽂件定位器到⽂件开始处
remove() 删除⽂件
fread() 从流中读指定个数的字符
fwrite() 向流中写指定个数的字符
tmpfile() ⽣成⼀个临时⽂件流
tmpnam() ⽣成⼀个唯⼀的⽂件名
下⾯就介绍⼀下这些函数
1.fopen()
fopen的原型是:FILE *fopen(const char *filename,const char *mode),fopen实现三个功能
为使⽤⽽打开⼀个流
把⼀个⽂件和此流相连接
给此流返回⼀个FILR指针
参数filename指向要打开的⽂件名,mode表⽰打开状态的字符串,其取值如下表
字符串 含义
"r" 以只读⽅式打开⽂件
"w" 以只写⽅式打开⽂件
"a" 以追加⽅式打开⽂件
"r+" 以读/写⽅式打开⽂件,如⽆⽂件出错
"w+" 以读/写⽅式打开⽂件,如⽆⽂件⽣成新⽂件
⼀个⽂件可以以⽂本模式或⼆进制模式打开,这两种的区别是:在⽂本模式中回车被当成⼀个字符'\n',⽽⼆进制模式认为它是两个字符0x0D, 0x0A;如果在⽂件中读到0x1B,⽂本模式会认为这是⽂件结束符,也就是⼆进制模型不会对⽂件进⾏处理,⽽⽂本⽅式会按⼀定的⽅式对数据作相应的转换。
系统默认的是以⽂本模式打开,可以修改全部变量_fmode的值来修改这个设置,例如_fmode=O_TEXT;就设置默认打开⽅式为⽂本模式;⽽_fmode=O_BINARY;则设置默认打开⽅式是⼆进制模式。
我们也可以在模式字符串中指定打开的模式,如"rb"表⽰以⼆进制模式打开只读⽂件,"w+t"或"wt+"表⽰以⽂本模式打开读/写⽂件。
此函数返回⼀个FILE指针,所以申明⼀个FILE指针后不⽤初始化,⽽是⽤fopen()来返回⼀个指针并与⼀个特定的⽂件相连,如果成败,返回NULL。
例:
FILE *fp;
if(fp=fopen("123.456","wb"))
puts("打开⽂件成功");
else
puts("打开⽂件成败");
2.fclose()
fclose()的功能就是关闭⽤fopen()打开的⽂件,其原型是:int fclose(FILE *fp);如果成功,返回0,失败返回EOF。
在程序结束时⼀定要记得关闭打开的⽂件,不然可能会造成数据丢失的情况,我以前就经常犯这样的⽑病。
例:fclose(fp);
3.fputc()
向流写⼀个字符,原型是int fputc(int c, FILE *stream); 成功返回这个字符,失败返回EOF。
例:fputc('X',fp);
4.fgetc()
从流中读⼀个字符,原型是int fputc(FILE *stream); 成功返回这个字符,失败返回EOF。
例:char ch1=fgetc(fp);
5. fseek()
此函数⼀般⽤于⼆进制模式打开的⽂件中,功能是定位到流中指定的位置,原型是int fseek(FILE *stream, long offset, int whence);如果成功返回0,参数offset是移动的字符数,whence是移动的基准,取值是
符号常量 值 基准位置
SEEK_SET 0 ⽂件开头
SEEK_CUR 1 当前读写的位置
SEEK_END 2 ⽂件尾部
例:fseek(fp,1234L,SEEK_CUR);//把读写位置从当前位置向后移动1234字节(L后缀表⽰长整数)
fseek(fp,0L,2);//把读写位置移动到⽂件尾
6.fputs()
写⼀个字符串到流中,原型int fputs(const char *s, FILE *stream);
例:fputs("I Love You",fp);
7.fgets()
从流中读⼀⾏或指定个字符,原型是char *fgets(char *s, int n, FILE *stream); 从流中读取n-1个字符,除⾮读完⼀⾏,参数s是来接收字符串,如果成功则返回s的指针,否则返回NULL。
例:如果⼀个⽂件的当前位置的⽂本如下
Love ,I Have
But ……..
如果⽤
fgets(str1,4,file1);
则执⾏后str1="Lov",读取了4-1=3个字符,⽽如果⽤
fgets(str1,23,file1);
则执⾏str="Love ,I Have",读取了⼀⾏(不包括⾏尾的'\n')。
8.fprintf()
按格式输⼊到流,其原型是int fprintf(FILE *stream, const char *format[, argument, …]);其⽤法和printf()相同,不过不是写到控制台,⽽是写到流罢了
例:fprintf(fp,"%2d%s",4,"Hahaha");
9.fscanf()
从流中按格式读取,其原型是int fscanf(FILE *stream, const char *format[, address, …]);其⽤法和scanf()相同,不过不是从控制台读取,⽽是从流读取罢了。
例:fscanf(fp,"%d%d" ,&x,&y);
10.feof()
检测是否已到⽂件尾,是返回真,否则返回0,其原型是int feof(FILE *stream);
例:if(feof(fp))printf("已到⽂件尾");
11.ferror()
原型是int ferror(FILE *stream);返回流最近的错误代码,可⽤clearerr()来清除它,clearerr()的原型是void clearerr(FILE
*stream);
例:printf("%d",ferror(fp));
把当前的读写位置回到⽂件开始,原型是void rewind(FILE *stream);其实本函数相当于fseek(fp,0L,SEEK_SET);
例:rewind(fp);
删除⽂件,原型是int remove(const char *filename); 参数就是要删除的⽂件名,成功返回0。
例:remove("c:\\io.sys");
13.fread()
从流中读指定个数的字符,原型是size_t fread(void *ptr, size_t size, size_t n, FILE *stream);参数ptr是保存读取的数据,void*的指针可⽤任何类型的指针来替换,如char*、int *等等来替换;size是每块的字节数;n是读取的块数,如果成功,返回实际读取的块数(不是字节数),本函数⼀般⽤于⼆进制模式打开的⽂件中。
例:
char x[4230];
FILE *file1=fopen("c:\\msdos.sys","r");
fread(x,200,12 ,file1);//共读取200*12=2400个字节
14.fwrite()
与fread对应,向流中写指定的数据,原型是size_t fwrite(const void *ptr, size_t size, size_t n, FILE *stream);参数ptr是要写⼊的数据指针,void*的指针可⽤任何类型的指针来替换,如char*、int *等等来替换;size是每块的字节数;n是要写的块数,如果成功,返回实际写⼊的块数(不是字节数),本函数⼀般⽤于⼆进制模式打开的⽂件中。
例:
char x[]="I Love You";
fwire(x, 6,12,fp);//写⼊6*12=72字节
将把"I Love"写到流fp中12次,共72字节
其原型是FILE *tmpfile(void); ⽣成⼀个临时⽂件,以"w+b"的模式打开,并返回这个临时流的指针,如果失败返回NULL。在程序结束时,这个⽂件会被⾃动删除。
例:FILE *fp=tmpfile();
其原型为char *tmpnam(char *s); ⽣成⼀个唯⼀的⽂件名,其实tmpfile()就调⽤了此函数,参数s⽤来保存得到的⽂件名,并返回这个指针,如果失败,返回NULL。
例:tmpnam(str1);
⼆、直接I/O⽂件操作
这是C提供的另⼀种⽂件操作,它是通过直接存/取⽂件来完成对⽂件的处理,⽽上篇所说流式⽂件操作是通过缓冲区来进⾏;流式⽂件操作是围绕⼀个 FILE指针来进⾏,⽽此类⽂件操作是围绕⼀个⽂件的“句柄”来进⾏,什么是句柄呢?它是⼀个整数,是系统⽤来标识⼀个⽂件(在WINDOWS中,句柄的概念扩展到所有设备资源的标识)的唯⼀的记号。此类⽂件操作常⽤的函数如下表,这些函数及其所⽤的⼀些符号在io.h和fcntl.h中定义,在使⽤时要加⼊相应的头⽂件。
函数 说明
open() 打开⼀个⽂件并返回它的句柄
close() 关闭⼀个句柄
lseek() 定位到⽂件的指定位置
read() 块读⽂件
write() 块写⽂件
eof() 测试⽂件是否结束
filelength() 取得⽂件长度
rename() 重命名⽂件
chsize() 改变⽂件长度
下⾯就对这些函数⼀⼀说明:
1.open()
fgets和fgetc的区别 打开⼀个⽂件并返回它的句柄,如果失败,将返回⼀个⼩于0的值,原型是int open(const char *path, int access [, unsigned mode]); 参数path是要打开的⽂件名,access是打开的模式,mode是可选项。表⽰⽂件的属性,主要⽤于UNIX系统中,在
DOS/WINDOWS这个参数没有意义。其中⽂件的打开模式如下表。
符号 含义 符号 含义 符号 含义
O_RDONLY 只读⽅式 O_WRONLY 只写⽅式 O_RDWR 读/写⽅式
O_NDELAY ⽤于UNIX系统 O_APPEND 追加⽅式 O_CREAT 如果⽂件不存在就创建
O_TRUNC 把⽂件长度截为0 O_EXCL 和O_CREAT连⽤,如果⽂件存在返回错误 O_BINARY ⼆进制⽅式
O_TEXT ⽂本⽅式
对于多个要求,可以⽤"|"运算符来连接,如O_APPEND|O_TEXT表⽰以⽂本模式和追加⽅式打开⽂件。
例:int handle=open("c:\\msdos.sys",O_BINARY|O_CREAT|O_WRITE)
2.close()
关闭⼀个句柄,原型是int close(int handle);如果成功返回0
例:close(handle)
3.lseek()
定位到指定的位置,原型是:long lseek(int handle, long offset, int fromwhere);参数offset是移动的量,fromwhere是移动的基准位置,取值和前⾯讲的fseek()⼀样,SEEK_SET:⽂件⾸部;SEEK_CUR:⽂件当前位置;SEEK_END:⽂件尾。此函数返回执⾏后⽂件新的存取位置。
例:
lseek(handle,-1234L,SEEK_CUR);//把存取位置从当前位置向前移动1234个字节。
x=lseek(hnd1,0L,SEEK_END);//把存取位置移动到⽂件尾,x=⽂件尾的位置即⽂件长度
从⽂件读取⼀块,原型是int read(int handle, void *buf, unsigned len);参数buf保存读出的数据,len是读取的字节。函数返回实际读出的字节。
例:char x[200];read(hnd1,x,200);
5.write()
写⼀块数据到⽂件中,原型是int write(int handle, void *buf, unsigned len);参数的含义同read(),返回实际写⼊的字节。
例:char x[]="I Love You";write(handle,x,strlen(x));
类似feof(),测试⽂件是否结束,是返回1,否则返回0;原型是:int eof(int handle);
例:while(!eof(handle1)){……};
8.filelength()
返回⽂件长度,原型是long filelength(int handle);相当于lseek(handle,0L,SEEK_END)
例:long x=filelength(handle);
重命名⽂件,原型是int rename(const char *oldname, const char *newname); 参数oldname是旧⽂件名,newname是新⽂件名。成功返回0
例:rename("c:\\config.sys","c:\\config.w40");
10.chsize();
改变⽂件长度,原型是int chsize(int handle, long size);参数size表⽰⽂件新的长度,成功返回0,否则返回-1,如果指定的长度⼩于⽂件长度,则⽂件被截短;如果指定的长度⼤于⽂件长度,则在⽂件
后⾯补'\0'。
例:chsize(handle,0x12345);
--------------------------------------------------------------------------------
如果熟悉汇编可能会发现这种⽅式和汇编语⾔的DOS功能调⽤句柄式⽂件操作很像,⽐如open()就像DOS服务的3CH号功能调⽤,其实这种操作还有两种类型的函数就是直接⽤DOS功能来完成的,如_open(),_dos_open()等等。有兴趣可⾃已查询BCB的帮助。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论