5.9 定位流
有三种方法定位标准I/O流。
(1) ftell和fseek。它们都假定文件的位置可以存放在一个长整型中。
(2) ftello和fseeko函数。Single UNIX Specification引入了这两个函数,可以使文件偏移量不必一定使用长整形。它们使用off_t数据类型代替了长整形。
(3) fgetpos和fsetpos。这两个函数是新由ANSI C引入的。它们引进了一个新的抽象数据类型fpos_t,它记录文件的位置。这种数据类型可以定义为记录一个文件的位置所需的长度。
需要移植到非UNIX系统上运行的应用程序应当使用fgetpos和fsetpos。
#include <stdio.h>
long ftell(FILE* fp); //成功返回当前文件位置指示,出错返回-1L;
int fseek(FILE*fp, long offset, int whence); //成功返回0,出错返回非0;
void rewind(FILE*fp);
对于一个二进制文件,其位置指示器是从文件起始位置开始度量,并以字节为计量单位的。ftell用于二进制文件时,其返回值就是这种字节位置。为了用fseek定位一个二进制文件,必须指定一个字节offset,以及解释这种位移量的方式。whence的值与lseek函数的相同:SEEK_SET表示从文件的起始位置开始,SEEK_CUR表示从当前文件位置,SEEK_END表示从文件的尾端。ANSI C并不要求一个实现对二进制文件支持SEEK_END规格说明,其原因是某些系统要求二进制文件的长度是某个幻数的整数倍,非实际内容部分则充填为0。但是在UNIX中,对于二进制文件SEEK_END是得到支持的。
对于文本文件,它们的文件当前位置可能不以简单的字节位移量来度量。再一次,这主要也是在非UNIX系统中,它们可能以不同的格式存放文本文件。为了定位一个文本文件,whence一定要是SEEK_SET,而且offset只能有两种值:0(表示反绕文件至其起始位置)或是对该文件的ftell所返回的值。使用rewind函数也可将一个流设置到文件的起始位置。
除了offset的类型是off_t而非long以外,ftello与ftell相同,fseeko与fseek相同。
#include <stdio.h>
off_t ftello(FILE*fp);//成功返回当前文件位置指示,出错返回-1;
int fseeko(FILE*fp, off_t offset, int whence);//成功返回0,出错返回非0;
int fgetpos(FILE*restrict fp,fpos_t*restrict pos);//成功返回0,出错返回非0;
int fsetpos(FILE*restrict fp,constfpos_t*pos);//成功返回0,出错返回非0;
fgetpos将文件位置指示器的当前值存入由pos指向的对象中。在以后调用fsetpos时,可使用此值将流重新定位至该位置。