Chinaunix首页 | 论坛 | 博客
  • 博客访问: 72201
  • 博文数量: 19
  • 博客积分: 485
  • 博客等级: 下士
  • 技术积分: 154
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-25 17:14
文章分类
文章存档

2013年(1)

2012年(10)

2011年(8)

分类: LINUX

2012-05-15 14:38:31

文件流的缓冲模式有三种:
_IONBF unbuffered(不带缓冲)
_IOLBF line buffered(行缓冲)
_IOFBF fully buffered(全缓冲)
在对文件以流形式进行操作时,文件表项中的位移量因流的缓冲模式类型不同而不同,如下代码:
#include
#include
#include
#include


int main(int argc, char *argv[])
{
int fp;
FILE *PF;
int i=0;
unsigned char  c;
PF=fopen(argv[1],"r");

fp=fileno(PF);

if(fork()==0)
{
       c=fgetc(PF);
  printf("child%c\n",c);
        
printf("offset of file is %d\n",lseek(fp,0,SEEK_CUR));
sleep(1);
        
        fclose(PF);
        return(1);
}
else{
        sleep(1);
//      rewind(PF);
        c=fgetc(PF);
        printf("parent %c\n",c);
        return(1);
        }
return 0;
}
在编译之后,以./test a.c运行,a.c文件包含1000多左右字符,程序的实际输出如下
#a
#offset of file is 1295
#parent ▒
造成上述结果是因为父子进程中的文件描述项指向同一文件表项,也即共享其中的状态标志和位移量,而子进程在进行fgetc操作时因PF所指向的文件的系统对流缓冲模式默认为全缓冲,造成fgetc读入的内容长度为全缓冲决的默认长度,文件偏移量也相应偏移对应缓冲块长度,因此文件长度(1295)小于缓冲块的默认长度,文件偏移量也变为1295,父进程再次进行fgetc操作时也相应地从1295处开始,造成其所读内容为▒(数值255所对应文件字符).
若对上述程序进行如下修改,也即在
int main(int argc, char *argv[])
{
int fp;
FILE *PF;
int i=0;
unsigned char  c;
PF=fopen(argv[1],"r");

fp=fileno(PF);

if(fork()==0)
{
setvbuf(PF, NULL, _IONBF, 0);
//设置文件流缓冲模式为无缓冲
       c=fgetc(PF);
  printf("child%c\n",c);
        
printf("offset of file is %d\n",lseek(fp,0,SEEK_CUR));
sleep(1);
        
        fclose(PF);
        return(1);
}
else{
        sleep(1);
//      rewind(PF);
        c=fgetc(PF);
        printf("parent %c\n",c);
        return(1);
        }
return 0;
}
此时文件实际输出内容为
child#
offset of file is 1
parent i
总结:
对文件进行流模式操作时,其虽带来一定的便捷,但也在某些可能情况下带来问题,特别是在多进程对同一文件进行操作环境需加以特别关注

阅读(1322) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~