文件读写(标准库)
文件缓冲区
-
设置缓冲区
文件读取时,不会直接对磁盘进行读取,而是先打开数据流,将磁盘上的文件信息拷贝到缓冲区内,然后程序再从缓冲区中读取所需数据。 -
不设置缓冲区
不设置缓冲区的文件处理方式,必须使用较低级的I/O函数(包含在头文件io.h和fcntl.h中)来直接对磁盘存取,这种方式的存取速度慢,并且由于不是 C++ 的标准函数,跨平台操作时容易出问题。
文件类型
文本文件
是以字符编码的方式进行保存的,只是计算机以二进制表示数据在外部存储介质上的另一种存放形式.它所存放的每一个字节都可以转换为一个可读字符当向文件中写入数据时,一旦遇到"换行"字符(ASCII 码为10)则会转换成"回车-换行"(ASCII 值为13,10).在读取数据的时候,一遇到"回车-换行"的组合 ASCII 值为13,10),则会转换成为"换行"字符(ASCII 码为10)
二进制文件
将内存中数据原封不动的读取和写入文件中,二进制文件的优点在于存取速度快,占用空间小,以及可随机存取数据。
文件存取方式
-
顺序读取
一个文件是由一个字节序列构成的。操作系统维护一个叫做文件指针(file pointer)的特殊标记,指向序列中的某个位置。读写操作都是在文件指针指向的位置进行。当文件打开时,文件指针被设置在文件开始位置。当读写数据时,文件指针会移动到下一个数据项。 -
随机存取方式
顺序访问的问题在于,如果我们想要读取一个特定位置的字节,那么必须读取它前面所有的字节,这样做效率太低了。所以C++引入了随机访问文件的概念,也就是说可以任意地向前或向后移动文件指针,而使用的函数是seekp和seekg函数。
seekp, seek put, 用于输出流
seekg, seek get, 用于输入流
// 单参, 参数指出绝对位置
seekg(0)
seekp(0)
// 多参, 偏移量(可正可负) + 定位基地址(seek base)
seekg(10,ios::beg)
seekp(-10,ios::end)
// ios::beg 文件开始基地址
// ios::end 文件结尾基地址
// ios::cur 文件指针当前位置
tellg() // 当前指针位置
// c语言对应
fseek()
ftell
// c++对应
C语言文件操作接口图
此图来自参考文献。
C语言文件操作接口说明(不常用)
- mode
“rt” 只读打开一个文本文件,只允许读数据
“wt” 只写打开或建立一个文本文件,只允许写数据
“at” 追加打开一个文本文件,并在文件末尾写数据
“rb” 只读打开一个二进制文件,只允许读数据
“wb” 只写打开或建立一个二进制文件,只允许写数据
“ab” 追加打开一个二进制文件,并在文件末尾写数据
“rt+” 读写打开一个文本文件,允许读和写
“wt+” 读写打开或建立一个文本文件,允许读写
“at+” 读写打开一个文本文件,允许读,或在文件末追加数据
“rb+” 读写打开一个二进制文件,允许读和写
“wb+” 读写打开或建立一个二进制文件,允许读和写
“ab+” 读写打开一个二进制文件,允许读,或在文件末追加数据
////////////////
r(read): 读 (打开只读文件,该文件必须存在)
w(write): 写 (打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失.若文件不存在则建立该文件)
a(append): 追加(以附加的方式打开只写文件.若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留)
t(text): 文本文件,可省略不写
b(banary): 二进制文件
+: 可读和写
- fflush
// 功能:会强迫将缓冲区内的数据写回参数 stream 指定的文件中.
// 如果参数 stream 为 NULL ,fflush() 会将所有打开的文件数据更新.
// 返回:成功返回 0
// 失败返回 EOF ,错误代码存于errno中.
int fflush(FILE* stream);
- setbuf
// 功能:打开文件流后,读取内容之前,调用 setbuf() 可以用来设置文件流的缓冲区
//
// 参数:stream为指定的文件流
// buf 指向自定的缓冲区起始地址.如果参数 buf 为 NULL 指针,则为无缓冲IO.Setbuf()
// 相当于调用 setvbuf(stream,buf,buf?_IOFBF:_IONBF,BUFSIZ)
void setbuf(FILE * stream,char * buf);
- setbuffer
// 功能:在打开文件流后,读取内容之前,调用 setbuffer() 可用来设置文件流的缓冲区.
//
// 参数:stream为指定的文件流
// buf 指向自定的缓冲区起始地址
// size 为缓冲区大小
void setbuffer(FILE * stream,char * buf,size_t size);
- setlinebuf
// 功能:用来设置文件流以换行为依据的无缓冲 IO.
// 相当于调用 setvbuf(stream,(char * )NULL,_IOLBF,0);
//
void setlinebuf(FILE * stream);
- setvbuf
// 功能:在打开文件流后,读取内容之前,调用 setvbuf() 可以用来设置文件流的缓冲区.
//
// 参数:stream为指定的文件流
// buf 指向自定的缓冲区起始地址
// size 为缓冲区大小
// mode 取值有下列几种
// _IONBF 无缓冲 IO
// _IOLBF 以换行为依据的无缓冲 IO
// _IOFBF 完全无缓冲 IO.如果参数 buf 为 NULL 指针,则为无缓冲 IO
int setvbuf(FILE * stream,char * buf,int mode,size_t size);
- fseek
// 参数:stream为指定的文件流
// offset 为根据参数whence来移动读写位置的位移数(offset 为整数时往后移, 为复数时往前移)
// whence为下列其中一种
// SEEK_SET 从距文件开头offset位移量为新的读写位置
// SEEK_CUR 以目前的读写位置往后增加offset个位移量
// SEEK_END 将读写位置指向文件尾后再增加offset个位移量。
int fseek(FILE * stream,long offset,int whence);
- rewind
// 功能:用来把文件流的读写位置移至文件开头。
// 参数 stream 为已打开的文件指针
void rewind(FILE * stream);
- clearerr
// 功能:清除 stream 指定的文件流所使用的错误旗标。
void clearerr(FILE * stream);
- fdopen
// 功能:会将参数fildes 的文件描述词,转换为对应的文件指针后返回。
// 参数:mode 字符串则代表着文件指针的流形态
FILE * fdopen(int fildes,const char * mode);
- feof
// 功能: feof()用来侦测是否读取到了文件尾,尾数stream为fopen()所返回之文件指针。
// 如果已到文件尾则返回非零值,其他情况返回0。
int feof(FILE * stream);
- fileno
// 功能: 用来取得参数stream指定的文件流所使用的文件描述词。
int fileno(FILE * stream);
- freopen
// 功能:原stream所打开的文件流关闭,然后打开参数path的文件
// 参数:path 字符串包含欲打开的文件路径及文件名
// mode 请参考fopen()说明
// stream 为已打开的文件指针
FILE * freopen(const char * pathconst char * mode,FILE * stream);
参考文献:
C++ 文件操作