查找一个流
2018-08-09 (星期四)
查找一个流
操纵当前的流位置往往会很有用.或许是应用程序正在读取一个基于记录的复杂文件.需要来回跳跃;亦或是流需要被重新设成文件位置零.无论是何种情况,标准I/O链接库提供了一系列功能相当于lseek()系统调用的接口,例如,fseek()函数(最常见的标准I/O查找接口)会根据offset与whence来操纵stream的文件位置.
#include <stdio.h> int fseek(FILE *stream, long offset, int whence);
如果whence的值被设为SEEK_SET,则文件位置会被设成offset;如果whence的值被设为SEEK_CUR,则文件位置会被设成当前位置加上offset;如果,whence的值被设为SEEK_END,则文件位置被设成文件末端加上offset.
执行成功时,fseek()会返回0,清除EOF指示器并消除ungetc()所造成的影响(如果有的话);发生错误时,它返回-1并且将error设定为设定的值.最常见的错误是无效的流(EBADF)以及无效的whence参数(EINVAL).
此外,标准I/O链接库还提供了fsetpos():
#include <stdio.h>
int fsetpos(FILE *stream, fpos_t *pos);
此函数会讲stream的流位置设置pos.它的功能如同将whence参数设为SEEK_SET的fseek().执行成功时,它会返回0;否则,它会返回-1并且将errno设定成设定成适当的值.之所以提供此函数(以及它的反向操作fgetpos(), 稍后会提到),只是因为其他(非Unix的)平台具体复杂的数据类型可以表示流位置.在其他平台上,如果C的long数据类型不够使用,此函数是将流位置设成任意值的唯一方法.如果想让你的Linux应用程序移植到所有可能的平台,就不应该让他们使用此接口,尽管他们可以这么做.
标准I/O链接库还提供了rewind()以作为一个捷径:
#include <stdio.h>
void rewind(FILE *stream);
如下的调用:
rewind(stream);
会将位置重新设定成流的开头.除了还会清除错误指示器,它的功能如同:
fseek(stream, 0, SEEK_SET);
注意,rewind()没有返回值,因此无法直接传达错误的情况.想确定发生错误的调用者,调用此函数之前就应该先清楚errno, 以便时候检查此变量是否为非零值.例如:
errno = 0; rewind (stream); if (errno) /* 错误 */