本文共 4324 字,大约阅读时间需要 14 分钟。
读yuv文件的时候需要获取yuv文件的帧数,以便建立循环一帧一帧读取,这时候要获取yuv的帧数。
方法:首先用fopen函数打开一个yuv文件,接着用fseek( fYUV, 0L, SEEK_END ),再接着用ftell来获取文件的大小size,由于用的是yuv420,因此用size/(WIDTH*HEIGHT*1.5)即获得了yuv文件的总帧数。
需要注意的是:fseek函数已把指向yuv文件的开始的指针改变了位置,即此时的指针已指向文件的结尾处,由于接着要进行文件的读写,这时候应该用rewind()函数把指针直接重新指到文件开始处。
ps:获得文件大小的几种方法
VS2005:若编译链接不通过,需要修改工程设置:
(1) Configuration Properties -> C/C++ -> Code Generation -> Runtime Library, 选择"Multi-threaded Debug(/MTd)"
(2) Configuration Properties -> Linker -> Input -> Ignore Specific Library, 输入"msvcprtd.lib"
例子中,由于在工程打开状态下,test.ncb文件无法打开,所以方法二、三无法获取文件大小,因此推荐使用方法一、四。
另:文件的随机读写
前面介绍了对文件的顺序读写操作,这些操作都是从文件的第一个有效数据(或某个位置)开始的,依照数据在文件存储设备中的先后次序进行读写,在读写过程中,文件位置指针自动移动。但在实际应用中,往往需要对文件中某个特定位置处的数据进行处理,换言之,就是读完一个字节的内容后,并不一定要读写其后续的字节数据,可能会强制性地将文件位置指针移动到用户所希望的特定位置,读取该位置上的数据,这就是随机读写文件。
C语言提供了对文件的随机读写功能。在随机方式下,系统并不按数据在文件中的物理顺序进行读写,而是可以读取文件任何有效位置上的数据,也可以将数据写入到任意有效的位置。
C语言通过提供文件定位函数来实现随机读写功能。
1. 获取文件位置指针当前值的函数ftell()
ftell()函数的功能是获得并返回文件位置指针的当前值。ftell()函数的原型定义为:
long ftell(FILE * fp);
其中参数fp是文件型指针,指向当前操作的文件。
rewind()函数的返回值为文件位置指针的当前位置。如果rewind()函数执行时出现错误,则返回长整型的-1(即-1L)。
2. 重置文件位置指针的函数rewind()
rewind()函数的功能是使文件的位置指针移到文件的开头处。rewind()函数的原型定义为:
void rewind(FILE * fp);
其中参数fp是文件型指针,指向当前操作的文件。
rewind()函数没有返回值,其作用在于:如果要对文件进行多次读写操作,可以在不关闭文件的情况下,将文件位置指针重新设置到文件开头,从而能够重新读写此文件。如果没有rewind()函数,每次重新操作文件之前,需要将该文件关闭后再重新打开,这种方式不仅效率低下,而且操作也不方便。使用rewind()函数便能克服这一缺陷。
【例11.7】 有一个文本文件file1.dat,两次读写它的内容,第一次将它的内容显示在屏幕上,第二次将它的内容复制到另一个文件fiel2.dat上。以下为实现该功能的程序代码。
#include "stdio.h"
void main()
{
FILE *fp1,*fp2;
fp1=fopen("file1.dat","r");
fp2=fopen("fiel2.dat","w");
while(!feof(fp1))
putchar(getc(fp1));
rewind(fp1);
while(!feof(fp1))
putc(getc(fp1),fp2);
fclose(fp1);
fclose(fp2);
}
3. 移动文件位置指针的函数fseek()
函数fseek()可以实现改变文件位置指针到指定位置的操作。fseek()函数的原型定义为:
int fseek(FILE * fp,long offset,int origin);
即:int fseek(文件类型指针,位移量,起始点);
其中fp为打开的文件指针,参数offset为文件位置指针移动的位移量(单位为字节),参数origin指示出文件位置指针移动的起始点(或称基点)位置。当执行fseek()函数后,文件位置指针新的位置是以起始点为基准,向后(offset为正值)/或向前(offset为负值)移动offset个字节。文件位置指针的新位置可以用公式“origin+offset”来计算得出。
二进制文件的基点origin 可以取以下三个常量值之一:
⑴SEEK_SET(也可直接用数字0表示):此时文件位置指针从文件的开始位置进行移动;
⑵SEEK_CUP(对应值为1): 此时文件位置指针从文件的当前位置进行移动;
⑶SEEK_END(对应值为2): 此时文件位置指针从文件的结束位置进行移动。
文本文件的基点origin只能取SEEK_SET常量值(或取0值),而origin的值应为0。
fseek()函数常用于二进制文件中,对于文本文件则不常使用,因为文本文件要进行字符的转换,这会为文件位置指针的计算带来混乱。fseek()函数的调用形式为:
fseek()函数返回一个整形值。如果函数执行成功,返回0值;否则,返回一个非0值。
下面给出fseek()函数调用的两个例子:
①fseek(fp,50L,1),将fp指向的文件的位置指针向后移动到离当前位置50个字节处;
②fseek(fp,-100L,2),将fp指向的文件的位置指针从文件末尾处向前回退100个字节。
4. 应用实例
【例11.8】 在当前目录下有一二进制文件information.dat,文件中存储有学生信息数据。编程实现按指定位置读取该文件中的数据,显示到屏幕上,并统计文件的总字节数目,也显示到屏幕上。
以下为实现该功能的程序代码。
#include "stdio.h"
struct student
{
char name[20];int num;
};
/*主函数*/
main()
{
int i=0;
long n=0;
FILE *fp=NULL;
struct student a = {0};
fp = fopen("information.dat","rb");
if(fp==NULL)
{
printf("Can't open!/n");
exit(0);
}
printf("Record in file information.dat:/n");
for(i=1;i<5;i+=2)
{
fseek(fp,i*sizeof(struct student),SEEK_SET); /*定位文件位置指针*/
n=ftell(fp); /*获取文件位置指针当前值*/
fread(&a,sizeof(struct student),1,fp); /*读取数据块*/
printf("current:%ldth byte,%dth record:%s %d/n",n,i+1,a.name,a.num);
fseek(fp,-3l*sizeof(struct student),2); /*重新定位文件位置指针*/
n=ftell(fp); /*重新读取数据块*/
fread(&a,sizeof(struct student),1,fp);
printf("current:%ldth btype,record is:%s %d/n",n,a.name,a.num);
rewind(fp); /*重置文件位置指针到文件开始*/
n=ftell(fp); /*获取文件位置指针当前值*/
fread(&a,sizeof(struct student),1,fp);
printf("current:%ldth btype,frist record :%s %d/n",n,a.name,a.num);
/*重新定位文件位置指针到文件尾部*/
fseek(fp,-0l*sizeof(struct student),2);
n=ftell(fp); /*计算文件总字节数目*/
printf("total bytes:%ld/n",n); /*显示文件总字节数目*/
fclose(fp);
}
getch();
}
转载地址:http://auqci.baihongyu.com/