文件偏移量与C语言中的流定位

一、文件偏移量

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 );
}
 








猜你喜欢

转载自blog.csdn.net/zxx910509/article/details/56682312
今日推荐