c语言判断文件是否结束问题

c语言判断文件是否结束问题,第1张

其实二进制方式和文本方式判断文件结束的方式是一样的,都是遇到EOF就认为文件结束,EOF是一个宏,它代表了-1这个值,如果在文件当中读到了0xff或者到了文件末尾,文件结构指针里面的flags字节的_F_EOF位都会被置为1,这一位被置为1,库函数就会认为到了文件末尾了。函数feof()其实是一个类函数宏,这个宏就是通过把文件结构指针的flags字节跟_F_EOF进行与运算来检测_F_EOF是否为1,并判断是否到了文件末尾的。这个函数具有与下面类似的代码:

#define feof(f) ((f)->flags & _F_EOF)

对于flags和_F_EOF,不同的编译器可能有不同的标识符。

feof是返回值为0表示遇到文件末尾的。上述那个_F_EOF应该是被置为0表示文件末尾,而feof是通过检测flags跟_F_EOF相与的结果是否为0来判断文件是否到了末尾。

另外提醒一下。刚刚查阅了一些更详细的资料,发现我所说的那种把-1当作文件结束标记的情况并非发生在所有的 *** 作系统上。某些 *** 作系统特别是早期的 *** 作系统有不少就把-1看作文件结束标记,但现在的 *** 作系统多数来说不再以这种方法判断文件结束,而是直接比较文件的大小,DOS、windows和一部分unix/linux就是以文件大小来判断的,当超过文件大小读的时候,就会设置_F_EOF和_O_EOF位。

一个ntfs文件系统由引导扇区、MFT(包含MFT元数据)和数据区组成。

NTFS中存储了两份MFT备份以防MFT文件损坏,两个MFT备份的具体起始位置都存储在引导扇区中。

引导扇区是从NTFS文件系统的第一个扇区开始,以55 AA结尾。我们主要关注前88字节的信息,其中重要的就是“NTFS”标识、扇区大小、每簇扇区数、MFT起始簇以及MFT备份MFTMirr位置这些信息。我们可以根据MFT起始簇信息找到MFT,或者根据MFT备份MFTMirr位置找到MFT的另外一个MFT备份。如下图所示:

MFT是什么,什么作用?

在NTFS中,整个卷的所有文件信息(包括MFT本身、数据文件、文件夹等等)都存储在MFT。每一个文件在 MFT 中都有一个或多个 MFT 项记录文件属性信息。而且每项大小是固定的(一般为1KB),MFT保留了前16项用于特殊文件记录,称为元数据。

可以根据MFT快速的找到文件的详细信息和具体位置等。

一个MFT项包括MFT头和关于文件的4条属性,以FF FF FF FF结尾。

在一个MFT项中前56字节是MFT头部信息,其中比较重要的是FILE标识、第一个属性的偏移和flags。

flags显示了此文件是否是正常文件,或者是删除文件等。

每条属性都包含属性头和属性结构。每条属性的前4字节显示该属性的类型,不同类型的属性有不同的属性结构。

具体属性头的大小根据是否是常驻属性来进行计算。

是否是常驻属性根据属性头的第9个字节判断,1为非常驻,0为常驻。

如果是非常驻属性,属性头大小为64;如果是常驻属性,属性头大小为24字节。

常驻和非常驻的区别:

常驻属性是直接保存再MFT中,非常驻属性保存再MFT之外的其他地方。如果文件或文件夹小于1500字节,那么它们的所有属性,包括内容都会常驻在MFT中。

不同类型的属性有不同的属性结构,这里主要介绍10H属性、30H属性和80H属性。

关于文件传统属性,对照下表:

这个属性比较重要,包含了文件的详细资料和父目录的参考号等。根据父目录参考号可以知道文件之间的父子关系,从而构建文件的子父关系。

其实在10H属性中已经描述了文件的部分信息(时间、标志等),30H属性主要关注父目录的参考号、文件名命名空间和文件名。

NTFS通过为一个文件创建多个30H属性实现POSIX (Portable Operating System Interface, 可移植 *** 作系统接口) 式硬连接,每个30H属性都有自己的详细资料和父目录;一个硬连接删除时,就从MFT中删除这个文件名,最后一个硬连接被删除时,这个文件就算是真正被删除了。

LCN(logical cluster number):整个文件卷的相对位置,单位(簇)。

VCN(virtual cluster number):文件内部的相对位置,单位(簇)。

每个运行列表中第一个字节的低4位表示运行簇大小(filesize)的len,高4位表示起始簇(start)的len。如果一个运行列表后面的第一个字节是00,说明运行列表结束,后面的数值暂时不用管;如果不是00,则是下一个运行列表开始。

0x00~0x3F 是属性头;运行列表在橘黄色框中,0x40开始,可以得到运行列表 33 40 BC 00 00 00 0C。

分析如下:

首先0x33,低4位是3,表示紧随其后的3Byte 0xBC40作为运行簇大小(簇个数),即文件所占总大小;高4位是3,表示簇大小之后的3个Byte 0x0C0000 是起始簇,即文件起始,这里是说的是LCN。

分析如下:

第一个运行列表,首先是0x31,低4位是1,表示紧接着的1Byte(03)是运行簇大小;高4位是3,表示紧接着3Byte(65 9A 00)是起始簇,这里说的是LCN;

第二个运行列表,首先是0x11,低4位是1,表示紧接着的1Byte(01)是运行簇大小;高4位是1,表示紧接着3Byte(13)是起始簇,这里说的是VCN。

注意,只有第一个运行列表的起始簇说的是LCN,从第二个运行列表开始每个运行列表的起始簇都说的是VCN。想要得到LCN需要按下面的公式计算:

第n个运行列表的LCN = 第一个运行列表的起始簇(LCN) + 第二个运行列表的起始簇(VCN) +...+第n个运行列表的起始簇(VCN)

1、从引导扇区找到“MFT起始簇”或者”MFT备份MFTMirr位置“;

2、根据“MFT起始簇”或者”MFT备份MFTMirr位置“找到第一个MFT项(1KB),第一个MFT项就是$MFT的属性内容;

3、在第一个MFT项中找到80H属性,根据80H属性的属性结构找到文件起始和总大小;

4、上面3找到的就是MFT文件的起始和总大小了。

MFT文件是对NTFS中全部MFT(卷上的所有文件,包括文件名、时间戳、流名和数据流所在的群集号列表、索引、安全标识符以及诸如“只读”、“压缩”、“加密”之类的文件属性)的存储,可以根据MFT文件快速的查找卷上的所有文件;而MFTMirr文件是对MFT文件中比较重要项的复制,一般是4KB。

参考:

https://www.cnblogs.com/mwwf-blogs/archive/2015/05/04/4467687.html

https://en.wikipedia.org/wiki/NTFS#Master_File_Table?tdsourcetag=s_pcqq_aiomsg

https://wenku.baidu.com/view/f204bb89e518964bce847cae.html

备注:如果想了解其他类型的属性,详见参考文章。

参考: https://www.jianshu.com/p/529c3729f357

mp4文件由box组成,每个box由box header 和 box body组成;box header有size和type字段,各4个字节

size大小包含box header本身的大小,type一般是4个ascii码字符,如"moov"。box header一般还有其他字段。

用户可以使用type为"uuid"自定义box。

下面讲下mp4的box组成:

ftyp:

一般第一个是类型为"ftyp"的box,表示mp4的版本信息以及兼容信息

moov:

紧接着是"moov" box,里面封装了mp4的metadata信息,moov是一个容器box,封装了mvhd box以及

若干个tracker box,

mvhd中封装的主要7个字段为:

version:版本

创建时间

修改时间

timescal:表示了metadata中使用的时间刻度,timescal的值对应真实时间的1秒。真正时长 = duration / timescal

duration

rate:推荐播放速度

volume:推荐音量

与mvhd box同一级的是tracker box:mp4包含若干tracker,至少包含一个,tracker之间是独立的,有自己的时间和空间信息

trak必须包含一个tkhd和一个mdia

tkhd包含字段:

version:box版本

flags:表示track的有效性

track id: track id号,不能重复且不能为0

duration:track的时间长度

volume: 音量大小

width:宽

height:高,用于播放时展示的宽、高。

media必须包含如下box:

播放时,mp4数据解析过程如下:

如播放到某个时间点时,例如8s处,则


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/8146781.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-13
下一篇 2023-04-13

发表评论

登录后才能评论

评论列表(0条)

保存