一、文件偏移量
1、每个打开的文件都有一个与其相关联的“当前文件偏移量”。它通常是一个非负整数,用以度量从文件开始处计算的字节数。
2、内核为所有打开的文件维持一张文件表。文件表项包含文件偏移量。
3、默认情况下,当打开一个文件时,除非指定O_APPEND选项,否则偏移量为0。
4、读、写操作都是从当前文件偏移量处开始,并使偏移量被设置为0.
5、两个进程打开同一个文件时,每个进程都会有自己的文件表项(只有一个V节点),都有自己对该文件的当前文件偏移量。
6、文件的定位可以大于文件的当前长度,此时,对文件的下一次写将加长该文件,并在文件中构成一个空洞。位于文件中但没有写过的字节都被读为0。文件中的空洞并不要求在磁盘上占用存储区。
7、文件的当前偏移量可能为负值。但是普通文件的当前偏移量必须为非负值。
8、管道型文件(比如fifo、socket、pipe)不可以设置文件位置偏移量。
二、定位标准I/O流
1、ftell
扫描二维码关注公众号,回复:
3793814 查看本文章
long ftell(
FILE* stream
);
测试文件的当前位置。成功时返回当前文件位置指示,若出错返回-1L.
2、fseek
定位文件位置。
(1)函数原型
int fseek(
FILE* stream,
long offset,
int origin
);
(2)参数
offset:离origin的偏移字节
origin:SEEK_CUR:文件当前位置;SEEK_END:文件尾;SEEK_SET:文件开头
(3)返回值
成功时返回0;失败时返回-1.
因为偏移量可能为负值,因此测试时不要测试是否小于0,而要测试是否等于-1。
- (4)说明
- 1)对于文本文件,它们的当前位置可能不能以简单的字节偏移量来衡量。因为可能以不同格式存放文本文件。
- 为了定位文本文件,origin必须为SEEK_SET,offset只能为0,或是对该文件的ftell返回的值。
- 2)对于二进制文件,文件位置指示器是从文件起始位置开始度量,并以字节为度量单位。ftell用于二进制文件时,其返回值就是字节位置。
- ISO C中并不要求对二进制文件支持SEEK_END,因为有些系统要求二进制文件的长度是某个幻数的整数倍,结尾非实际内容部分则填充为0.但是在UNIX中,对于二进制文件支持SEEK_END。
- 3)在文本文件中,输入时最后的CTRL+Z被解释为文件尾的字符。
- 使用fopen打开文件时,会检测最后的CTRL+Z,并把它移除。
-
- (5)示例
/* FSEEK.C: This program opens the file FSEEK.OUT and
* moves the pointer to the file's beginning.
*/
#include <stdio.h>
void main( void )
{
FILE *stream;
char line[81];
int result;
stream = fopen( "fseek.out", "w+" );
if( stream == NULL )
printf( "The file fseek.out was not opened\n" );
else
{
fprintf( stream, "The fseek begins here: "
"This is the file 'fseek.out'.\n" );
result = fseek( stream, 23L, SEEK_SET);
if( result )
printf( "Fseek failed" );
else
{
printf( "File pointer is set to middle of first line.\n" );
fgets( line, 80, stream );
printf( "%s", line );
}
fclose( stream );
}
}
3、rewind
void rewind(
FILE *stream
);
将一个流设置到文件的起始位置。
4、fgetpos、fsetpos
int fgetpos(
FILE *stream,
fpos_t *pos
);
int fsetpos(
FILE *stream,
const fpos_t *pos
);
(1)说明
这两个函数是ISO C引入的,使用抽象数据类型fpos_t记录文件位置。这种数据类型可以根据需要定义为一个足够大的数,用以记录文件位置。
需要移植到非UNIX系统上运行的应用程序应当使用fgetpos和fsetpos
(2)示例
// crt_fgetpos.c
// This program uses fgetpos and fsetpos to
// return to a location in a file.
#include <stdio.h>
int main( void )
{
FILE *stream;
fpos_t pos;
char buffer[20];
if( fopen_s( &stream, "crt_fgetpos.txt", "rb" ) ) {
perror( "Trouble opening file" );
return -1;
}
// Read some data and then save the position.
fread( buffer, sizeof( char ), 8, stream );
if( fgetpos( stream, &pos ) != 0 ) {
perror( "fgetpos error" );
return -1;
}
fread( buffer, sizeof( char ), 13, stream );
printf( "after fgetpos: %.13s\n", buffer );
// Restore to old position and read data
if( fsetpos( stream, &pos ) != 0 ) {
perror( "fsetpos error" );
return -1;
}
fread( buffer, sizeof( char ), 13, stream );
printf( "after fsetpos: %.13s\n", buffer );
fclose( stream );
}