FLV 文件格式

    FLV(Flash Video)是现在非常流行的流媒体格式,由于其视频文件体积轻巧、封装播放简单等特点,使其很适合在网络上进行应用,目前主流的视频网站无一例外地使用了FLV格式。另外由于当前浏览器与Flash Player紧密的结合,使得网页播放FLV视频轻而易举,也是FLV流行的原因之一。
    FLV视频格式是Adobe公司设计开发的,目前已经免费开放,现在的版本是v10。下面我们就了解一下FLV文件格式。
    FLV是流媒体封装格式,我们可以将其数据看为二进制字节流。总体上看,FLV包括文件头(File Header)和文件体(File Body)两部分,其中文件体由一系列的Tag及Tag Size对组成。因此一个FLV文件看上去是下面的结构:

点击查看原图

    其中,Previous Tag Size紧跟在每个Tag之后,占4个字节表示一个UI32类型的数值,表示前面一个Tag的大小。需要注意的是,Previous Tag Size #0的值总是为0。Tag类型包括视频、音频和Script,且每个Tag只能包含一种类型的数据。下面我们看看File Header和Tag的具体结构,为了方便大家理解,我贴一个实际FLV文件的字节流图片,图片中把不同部分区分了颜色。

点击查看原图

 
一、File Header结构
    File Header在当前版本中总是由9个字节组成,如图中蓝色区域所示。
    第1-3字节为文件标识(Signature),总为“FLV”(0x46 0x4C 0x56),如图中紫色区域。
    第4字节为版本,目前为1(0x01)。
    第5个字节的前5位保留,必须为0。
    第5个字节的第6位表示是否存在音频Tag。
    第5个字节的第7位保留,必须为0。
    第5个字节的第8位表示是否存在视频Tag。
    第6-9个字节为UI32类型的值,表示从File Header开始到File Body开始的字节数,版本1中总为9。
 
二、Previous Tag Size结构
    如图中红色位置所示。
 
三、Tag结构
    Tag包括Tag Header和Tag Data两部分。不同类型的Tag的Header结构是相同的,但是Data结构各不相同。如图中绿色和黄色区域分别表示Tag Header数据和Tag Data数据。
    当前版本的Tag Header结构占用11个字节。
    第1个字节表示Tag类型,包括音频(0x08)、视频(0x09)和script data(0x12),其他类型值被保留。
    第2-4字节为UI24类型的值,表示该Tag Data部分的大小。
    第5-7字节为UI24类型的值,表示该Tag的时间戳(单位为ms),第一个Tag的时间戳总是0。
    第8个字节为时间戳的扩展字节,当24位数值不够时,该字节作为最高位将时间戳扩展为32位值。
    第9-11字节为UI24类型的值,表示stream id,总是0。
    后面的字节为Tag Data数据,Data的大小由第2-4字节的数值指示,根据第1个字节指示的Tag类型,按照不同的结构解析Tag Data。下面分别介绍。
 
四、Audio Tag Data结构
    音频Tag开始的第1个字节包含了音频数据的参数信息,从第2个字节开始为音频流数据。
    第1个字节的前4位的数值表示了音频数据格式,各值代表的意义大家可以查阅Adobe公司发布的FLV格式说明文档(可以到我的磁盘空间的“资料”目录去下载 http://e.ys168.com/?tinyfun)。
    第1个字节的第5-6位的数值表示采样率,0 = 5.5 kHz,1 = 11 kHz,2 = 22 kHz,3 = 44 kHz。
    第1个字节的第7位表示采样精度,0 = 8bits,1 = 16bits。
    第1个字节的第8位表示音频类型,0 = mono,1 = stereo。
 
五、Video Tag Data结构
    视频Tag也用开始的第1个字节包含视频数据的参数信息,从第2个字节开始为视频流数据。
    第1个字节的前4位的数值表示帧类型。
    第1个字节的后4位的数值表示视频编码ID,1 = JPEG(现已不用),2 = Sorenson H.263,3 = Screen video,4 = On2 VP6,5 = On2 VP6 with alpha channel,6 = Screen video version 2。
 
六、Script Tag Data结构
    该类型Tag又通常被称为Metadata Tag,会放一些关于FLV视频和音频的参数信息,如duration、width、height等。通常该类型Tag会跟在File Header后面作为第一个Tag出现,而且只有一个。
    一般来说,该Tag Data结构包含两个AMF包。AMF(Action Message Format)是Adobe设计的一种通用数据封装格式,在Adobe的很多产品中应用,简单来说,AMF将不同类型的数据用统一的格式来描述。第一个AMF包封装字符串类型数据,用来装入一个“onMetaData”标志,这个标志与Adobe的一些API调用有,在此不细述。第二个AMF包封装一个数组类型,这个数组中包含了音视频信息项的名称和值。具体说明如下,大家可以参照图片上的数据进行理解。
 
    第一个AMF包:
       第1个字节表示AMF包类型,一般总是0x02,表示字符串,其他值表示意义请查阅文档。
       第2-3个字节为UI16类型值,表示字符串的长度,一般总是0x000A(“onMetaData”长度)。
       后面字节为字符串数据,一般总为“onMetaData”。
 
    第二个AMF包:
       第1个字节表示AMF包类型,一般总是0x08,表示数组。
       第2-5个字节为UI32类型值,表示数组元素的个数。
       后面即为各数组元素的封装,数组元素为元素名称和值组成的对。表示方法如下:
       第1-2个字节表示元素名称的长度,假设为L。
       后面跟着为长度为L的字符串。
       第L+3个字节表示元素值的类型。
       后面跟着为对应值,占用字节数取决于值的类型。

Windows 7中如何禁用EFS加密

EFS加密服务的确是很安全,但是如果不是我们自己本意识的加密,可能就是一场灾难了,比如朋友或者家人在不经意给加密了并且你还不知道,密钥也没有备份就重装系统了后果....以下是禁用EFS加密功能的方法。

 

1、打开“开始>运行”,键入 secpol.msc ,回车,打开本地安全设置对话框。

点击查看原图

2、“安全设置>公钥策略>加密文件系统”项。右击“加密文件系统”,选择“属性”。

点击查看原图

3、在“常规”选项卡中,将“使用加密文件系统的文件加密”设置为“不允许”,再按“确定”保存设置。

点击查看原图

如果要恢复加密功能,重新选择“允许”即可。
禁用 EFS 加密后就不能给文件或文件加加密了,再次加密时会出现下面的错误提示:

点击查看原图

 

 

适用系统:
Windows 7 Professional(专业版),Windows 7 Enterprise(企业版),Windows 7 Ultimate(旗舰版)

Linux_Ext分区超级块结构

Chkdsk的新增开关 /C 和 /I 说明

 

Chkdsk.exe CHKDSK 程序的命令行界面,该程序用于验证文件系统的逻辑完整性。如果 CHKDSK 在文件系统数据中发现存在逻辑不一致性,CHKDSK 将执行可修复该文件系统数据的操作(前提是这些数据未处于只读模式)。

/C /I 开关仅对使用 NTFS 文件系统格式化的驱动器有效。这两个新的开关都指示 CHKDSK 例程跳过某些 CHKDSK 原本要执行以验证 NTFS 数据结构完整性的操作。

如果联机运行 CHKDSK,则实际执行验证的代码位于实用程序 DLL(例如 Untfs.dll Ufat.dll)中。CHKDSK 调用的验证例程与通过 Windows 资源管理器或磁盘管理图形用户界面验证卷时所运行的例程相同。

但是,如果将 CHKDSK 计划为在计算机重新启动时运行,则包含验证代码的二进制模块为 Autochk.exe,它是一个 Windows 固有程序。由于 Autochk.exe 在计算机启动序列中靠前的位置运行,Autochk.exe 不具有虚拟内存或其他 Win32 服务的优点。

Autochk.exe Chkdsk.exe 实用程序 DLL 生成相同种类的文本输出。Autochk.exe 在启动过程中显示这些文本输出,并在应用程序事件日志中记录事件。所记录的事件信息中包含事件日志的数据缓冲区所能容纳的最大数量的文本输出。

由于 Autochk.exe Chkdsk.exe 实用程序 DLL 中的验证代码都基于相同的源代码,因此本文的其余部分将使用术语“CHKDSK”来统称 Autochk.exe Chkdsk.exe。与此类似,由于本文仅讨论那些与 NTFS 卷有关的 CHKDSK 更改,因此,任何“CHKDSK 如何如何的语句的意思都是“CHKDSK NTFS 卷上运行时如何如何

请注意,如果您使用 /C /I 开关,则即使运行了 CHKDSK,卷仍可能是损坏的。因此,建议您仅在必须将停机时间降至最短的情况下才使用这些开关。这些开关适用于以下场合:必须在特别大的卷上运行 CHKDSK,并且需要灵活地管理所造成的停机时间。

要了解何时适于使用 /C /I 开关,您需要对某些内部的 NTFS 数据结构、可能发生的损坏的种类、CHKDSK 在验证卷时采取的操作以及回避 CHKDSK 的常规验证步骤可能有哪些后果等有一些基本的了解。

了解 CHKDSK 所采取的操作


CHKDSK 的活动分为三个主要阶段(在这三个阶段中,CHKDSK 将检查卷上的所有元数据),另外还有一个可选的第四阶段。

元数据是有关数据的数据。元数据是文件系统的系统开销,它跟踪有关所有在卷上存储的文件的信息。元数据包括有关以下方面的信息:给定文件的数据由哪些分配单元组成、哪些分配单元是可用的以及哪些分配单元包含坏扇区等。另一方面,文件包含的数据称为用户数据NTFS 通过使用事务日志来保护它的元数据。用户数据没有以这种方式进行保护。

阶段 1:检查文件


在第一个阶段,CHKDSK 会显示一条消息,通知您 CHKDSK 正在验证文件,同时还显示已完成的验证任务的百分比(范围为从 0% 100%)。在此阶段中,CHKDSK 将检查卷的主文件表 (MFT) 中的各个文件记录段。

MFT 中的特定文件记录段唯一地标识 NTFS 卷上的各个文件和目录。CHKDSK 在此阶段显示的已完成百分比 CHKDSK 已验证的 MFT 的百分比。在此阶段中,CHKDSK 将检查各个文件记录段的内部一致性,并生成两个位图,一个表示正在使用的文件记录段,另一个表示卷上正在使用的簇。

在此阶段结束时,CHKDSK 将会识别 MFT 内部和整个卷上的已用空间和可用空间。NTFS 在其自身的位图中跟踪这些信息,该位图存储在磁盘上。CHKDSK 将它的结果与 NTFS 保持的位图进行比较。如果存在差异,将在 CHKDSK 输出中记录这些差异。例如,如果发现正在使用的文件记录段损坏,则在 CHKDSK 位图中,与该文件记录段相关联的磁盘簇将被标记为可用,但在 NTFS 位图中,它将被标记为使用中

阶段 2:检查索引


在第二个阶段,CHKDSK 会显示一条消息,通知您 CHKDSK 正在验证索引,同时还显示已完成的验证任务的百分比(范围为从 0% 100%)。在此阶段中,CHKDSK 将检查卷上的各个索引。

索引实际上就是 NTFS 目录。在此阶段中,CHKDSK 显示的已完成百分比是已检查的卷目录总数的百分比。在此阶段中,CHKDSK 将检查卷上的各个目录,检查内部一致性,并验证 MFT 中的文件记录段所代表的每个文件和目录都至少由一个目录引用。CHKDSK 确认目录中引用的每个文件或子目录都实际作为有效的文件记录段存在于 MFT 中,并且还检查是否存在循环目录引用。最后,CHKDSK 将确认在文件的目录项中,这些文件的时间戳和文件大小信息都是最新的。

在此阶段结束时,CHKDSK 将确保没有孤立的文件,并且所有目录项都用于合法的文件。孤立文件是指存在该文件的合法文件记录段,但该文件却没有列在任何目录中。如果相应的目录仍存在,则孤立文件通常可以恢复到正确的目录中。如果正确的目录已不存在,CHKDSK 将在根目录中创建一个目录,并将文件放入该目录中。如果 CHKDSK 发现不再使用的文件记录段的目录项,或者虽然仍在使用但并不与目录中列出的文件相对应的文件记录段的目录项,CHKDSK 将直接删除该文件记录段的目录项。

阶段 3:检查安全描述符


在第三个阶段,CHKDSK 会显示一条消息,通知您 CHKDSK 正在验证安全描述符,同时还显示已完成的验证任务的百分比(范围为从 0% 100%)。在此阶段中,CHKDSK 将检查与卷上的文件或目录相关联的每个安全描述符。

安全描述符包含有关下列方面的信息:文件或目录的所有权、文件或目录的 NTFS 权限以及文件或目录的审核。在此阶段中,CHKDSK 显示的已完成百分比是卷上已检查的文件和目录的百分比。CHKDSK 将验证各个安全描述符的结构是否正常,并验证该结构的内部一致性。CHKDSK 并不验证列出的用户或组实际上是否存在,也不验证所赋予的权限是否适当。

阶段 4:检查扇区


如果 /R 开关生效,CHKDSK 将运行第四个阶段,以便在卷的可用空间中查找坏扇区。CHKDSK 将尝试读取卷上的每个扇区,以确认该扇区是否可用。即使不使用 /R 开关,CHKDSK 也总是读取与元数据相关联的扇区。如果指定了 /R 开关,将在 CHKDSK 的较早阶段读取与用户数据关联的扇区。

CHKDSK 找到不可读的扇区时,NTFS 会将包含该扇区的簇加入它的坏簇列表中。如果坏扇区正在使用,CHKDSK 将分配一个新的簇,以完成该坏簇的工作。如果您使用的是容错磁盘,NTFS 将恢复坏簇的数据,并将这些数据写入新分配的簇中。否则,新的簇中将填充某种模式的 0xFF 字节。

如果 NTFS 在正常运行过程中遇到不可读的扇区,NTFS 将以与运行 CHKDSK 时相同的方式重新映射这些扇区。因此,通常无须使用 /R 开关。但是,如果怀疑磁盘可能有坏扇区,则使用 /R 开关就是一个扫描整个卷的简便办法。

了解 CHKDSK 的时间要求


前面对 CHKDSK 的各个运行阶段的说明只是粗略概述了 CHKDSK 为验证 NTFS 卷的完整性而执行的最重要任务。CHKDSK 还在各个阶段中执行许多额外的特定检查,并在各个阶段之间执行几种快速检查。但是,即使是这样的粗略概述也能够提供一些基础知识,以便我们开始讨论影响 CHKDSK 运行所需时间的可变因素,以及讨论 Windows XP 中可以使用的新增 /C /I 开关的影响。

可变因素 1索引阶段


在运行 CHKDSK 的第一和第三阶段(检查文件和检查安全描述符),已完成百分比指示器的进度相对比较平滑。虽然未使用的文件记录段需要的处理时间的确较少,而大型安全描述符的确需要较多的处理时间,但是总体说来已完成百分比相当准确地反映了该阶段所需的实际时间。

不过,这一百分比/时间关系却未必适用于第二阶段,也就是 CHKDSK 检查索引(NTFS 目录)的那个阶段。处理目录所需的时间与该目录中包含的文件和子目录的数量密切相关,但是在该阶段中,已完成百分比仅与 CHKDSK 必须检查的目录数量有关。并没有针对某些特定操作(例如,处理包含数量巨大的文件和子目录的目录)所需的时间进行调整。除非卷上的目录都包含大致相同数量的文件,否则该阶段中显示的已完成百分比将不会可靠地反映第二阶段所需的实际时间。

更坏的情况是您可能陷入意外的 CHKDSK 过程,这时 CHKDSK 的第二阶段通常是需时最长的阶段。

可变因素 2:卷的情况


许多与卷的状态有关的因素都会影响 CHKDSK 运行所需的时间。用于预测在给定卷上运行 CHKDSK 所需时间的公式必须考虑文件和目录的数目、卷的总体碎片化程度(特别是 MTF 的碎片化程度)、文件名的格式(长名称、8.3 格式名称或混合型名称)以及 CHKDSK 必须修复的实际损坏量等可变因素。

可变因素 3:硬件问题


硬件问题也会影响 CHKDSK 运行所需的时间。可变因素包括可用内存的数量、CPU 速度、磁盘速度等。

可变因素 4CHKDSK 设置


如果不使用 /R 开关,则给定硬件平台上与时间最密切的因素是该卷上的文件和目录的数量,而不是卷的绝对大小。

例如,如果不使用 /R 开关,则对于仅包含一个或两个大型数据库文件的 50 GB 卷,CHKDSK 的运行可能只需要几秒钟。如果使用 /R 开关,CHKDSK 将必须读取并验证卷上的每个扇区,对于大型卷而言,这会显著增加运行所需的时间。另一方面,如果一个相对较小的卷包含几十万甚至几百万个小文件,则运行 CHKDSK 可能需要数小时,无论您是否指定 /R 开关。

预测 CHKDSK 的时间要求


如上所述,运行 CHKDSK 所需的时间从几秒到几天不等,这要由您的具体情况决定。预测对给定卷运行 CHKDSK 所需时间的最好办法是:在系统利用率较低的时段,以只读模式实际进行一次测试运行。

但是,出于以下原因,必须谨慎使用此方法:

·         在只读模式下,如果在较早阶段中遇到错误,CHKDSK 会在完成所有三个阶段之前退出,并很可能误报错误。例如,如果 NTFS 恰好在 CHKDSK 检查磁盘时修改了磁盘上的区域,则 CHKDSK 可能会报告磁盘损坏。要正确地进行验证,卷必须处于静止状态,而保证卷处于静止状态的唯一方法就是锁定卷。CHKDSK 仅当您指定了 /F 开关(或 /R 开关,它会隐含指定 /F)时才会锁定卷。在只读模式下,要使 CHKDSK 完成所有运行阶段,可能需要多次运行 CHKDSK

·         CHKDSK CPU 和磁盘的占用率都很高。运行 CHKDSK 所需的时间要受到系统负载的大小的影响,还要受到 CHKDSK 是联机运行还是在 Windows XP 启动序列内运行的影响。哪个因素成为瓶颈要视硬件配置而定,但是如果在只读模式下运行 CHKDSK CPU 利用率或磁盘 I/O 量很高,则 CHKDSK 的运行时间将变长。此外,Autochk.exe 的运行环境与 Chkdsk.exe 不同。通过 Autochk.exe 运行 CHKDSK 使 CHKDSK 能够独占 CPU I/O 资源,但同时还会使 CHKDSK 无法使用虚拟内存。虽然 Autochk.exe 一般比 Chkdsk.exe 运行速度更快,但如果计算机的可用 RAM 相对较少,Autochk.exe 可能实际上需要更长时间。

·         修复损坏会增加所需的时间。在只读模式下,仅当 CHKDSK 没有发现任何重大损坏时,才能完整运行。如果磁盘仅有少量损坏,那么修复这些问题不会显著增加仅仅运行 CHKDSK 所需的时间。但如果 CHKDSK 发现了重大损坏,例如发生了严重的硬件故障,则运行 CHKDSK 所需的时间将随 CHKDSK 必须修复的损坏文件的数量而成比例地增加。在极端情况下,这可能会成倍地增加 CHKDSK 运行所需的时间。

/C /I 开关简介


/C 开关


/C 开关指示 CHKDSK 跳过在目录结构中检测循环的检查步骤。循环是一种很罕见的损坏形式,此时子目录以其自身为祖先

使用 /C 开关可以将 CHKDSK 的运行速度提高大约 1% 2%,但使用此开关也可能会使目录在 NTFS 卷上循环。这样的循环可能无法从目录树的其余部分进行访问,而且一些文件可能会被孤立,这意味着 Win32 程序(包括备份程序)将无法看到这些文件。

/I 开关


/I 开关指示 CHKDSK 跳过将目录项与它们的对应文件记录段进行比较的检查步骤。应用此开关时,将仍对目录项进行内部一致性检查,但是目录项未必与相应文件记录段中存储的数据一致。

很难预测通过使用 /I 开关可以节省多少时间。通常,/I 开关可以节省 CHKDSK 50% 70% 的运行时间,具体取决于文件与目录个数之比以及磁盘 I/O 速度与 CPU 速度之比等因素。

使用 /I 开关有以下局限:

·         可能会产生引用错误文件记录段的目录项。这种情况下,任何试图使用此类项的程序都会遇到错误。

·         可能会产生没有目录项引用的文件记录段(这是产生孤立文件的另一种方式)。实际上完好无损的文件(如文件记录段所表示的那样)可能对所有的 Win32 程序(包括备份程序)都不可见。

/C /I 开关的价值


在卷上检测到磁盘损坏时,有三个基本的应对选择。

第一个选择是什么都不做。在需要全天 24 小时联机的使命关键服务器上,这通常是必要的选择。缺点是相对较轻的损坏会逐渐发展为重大的损坏。因此,仅当使服务器保持联机比确保损坏卷上所存储数据的完整性更为重要时,才应考虑此选择。在运行 CHKDSK 之前,损坏卷上的所有数据都应当被看作是危险的。 第二个选择是运行完整的 CHKDSK 操作,以修复所有文件系统数据并通过自动进程还原所有可以恢复的用户数据。但是,运行完整的 CHKDSK 操作可能会在不适当的时机使得使命关键服务器停机数小时。 第三个选择是通过使用 /C /I 开关中的一个或两个,修复可能会发展为更严重问题的损坏类型(这比完整 CHKDSK 所需的时间少得多),运行简化的 CHKDSK 操作。

但是,请注意,运行简化的 CHKDSK 并不能修复可能存在的所有损坏。您仍需要在将来某个时间运行完整的 CHKDSK,以确保所有可恢复的数据都已实际得到恢复。

另请注意,NTFS 在发生磁盘损坏后并不能保证用户数据的完整性,即使您立即运行了完整的 CHKDSK 操作。CHKDSK 可能无法恢复某些文件,而 CHKDSK 所恢复的某些文件可能内部仍是损坏的。因此,通过执行定期备份或使用某些其他的可靠的数据恢复方法来保护使命关键的数据,仍然是极其重要的。

使用CFile类对文件进行读写

  CFile类提供了对文件进行打开,关闭,读,写,删除,重命名以及获取文件信息等文件操作的基本功能,足以处理任意类型的文件操作

一个读写文件的例子:
文件I/O

  虽然使用CArchive类内建的序列化功能是保存和加载持久性数据的便捷方式,但有时在程序中需要对文件处理过程拥有更多的控制权,对于这种文件输入输出(I/O)服务的需求,Windows提供了一系列相关的API函数,并由MFC将其封装为CFile类,提供了对文件进行打开,关闭,读,写,删除,重命名以及获取文件信息等文件操作的基本功能,足以处理任意类型的文件操作。CFile类是MFC文件类的基类,支持无缓冲的二进制输入输出,也可以通过与CArchive类的配合使用而支持对MFC对象的带缓冲的序列化。

  CFile类包含有一个公有型数据成员m_hFile,该数据成员包含了同CFile类对象相关联的文件句柄。如果没有指定句柄,则该值为CFile::hFileNull。由于该数据成员所包含的意义取决于派生的类,因此一般并不建议使用m_hFile。

  通过CFile类来打开文件可以采取两种方式:一种方式是先构造一个CFile类对象然后再调用成员函数Open()打开文件,另一种方式则直接使用CFile类的构造函数去打开一个文件。下面的语句分别演示了用这两种方法打开磁盘文件“C:\TestFile.txt”的过程:

// 先构造一个实例,然后再打开文件
CFile file;
file.Open(“C:\\TestFile.txt”, CFile::modeReadWrite);
……
// 直接通过构造函数打开文件
CFile file(“C:\\TestFile.txt”, CFile::modeReadWrite);

  其中参数CFile::modeReadWrite是打开文件的模式标志,CFile类中与之类似的标志还有十几个,现集中列表如下:

文件模式标志 说明
CFile::modeCreate  创建方式打开文件,如文件已存在则将其长度设置为0
CFile::modeNoInherit  不允许继承
CFile::modeNoTruncate 创建文件时如文件已存在不对其进行截断
CFile::modeRead 只读方式打开文件
CFile::modeReadWrite 读写方式打开文件
CFile::modeWrite 写入方式打开文件
CFile::shareCompat 在使用过程中允许其他进程同时打开文件
CFile::shareDenyNone 在使用过程中允许其他进程对文件进行读写
CFile::shareDenyRead 在使用过程中不允许其他进程对文件进行读取
CFile::shareDenyWrite 在使用过程中不允许其他进程对文件进行写入
CFile::shareExclusive  取消对其他进程的所有访问
CFile::typeBinary 设置文件为二进制模式
CFile::typeText 设置文件为文本模式

  这些标志可以通过“或”运算符而同时使用多个,并以此来满足多种需求。例如,需要以读写方式打开文件,如果文件不存在就创建一个新的,如果文件已经存在则不将其文件长度截断为0。为满足此条件,可用CFile::modeCreate、CFile::modeReadWrite和CFile::modeNoTruncate等几种文件模式标志来打开文件:

CFile file ("C:\\TestFile.txt", CFile::modeCreate | CFile::modeReadWrite | CFile::modeNoTruncate);

  在打开的文件不再使用时需要将其关闭,即可以用成员函数Close()关闭也可以通过CFile类的析构函数来完成。当采取后一种方式时,如果文件还没有被关闭,析构函数将负责隐式调用Close()函数去关闭文件,这也表明创建在堆上的CFile类对象在超出范围后将自动被关闭。由于调用了对象的析构函数,因此在文件被关闭的同时CFile对象也被销毁,而采取Close()方式关闭文件后,CFile对象仍然存在。所以,在显式调用Close()函数关闭一个文件后可以继续用同一个CFile对象去打开其他的文件。

  文件读写是最常用的文件操作方式,主要由CFile类成员函数Read()、Write()来实现。其函数原型分别为:

UINT Read( void* lpBuf, UINT nCount );
void Write( const void* lpBuf, UINT nCount );

  参数lpBuf为指向存放数据的缓存的指针,nCount为要读入或写入的字节数,Read()返回的为实际读取的字节数,该数值小于或等于nCount,如果小于nCount则说明已经读到文件末尾,可以结束文件读取,如继续读取,将返回0。因此通常可以将实际读取字节数是否小于指定读取的字节数或是否为0作为判断文件读取是否到达结尾的依据。下面这段代码演示了对文件进行一次性写入和循环多次读取的处理过程:

// 创建、写入方式打开文件
CFile file;
file.Open("C:\\TestFile.txt", CFile::modeWrite | CFile::modeCreate);
// 写入文件
memset(WriteBuf, 'a', sizeof(WriteBuf));
file.Write(WriteBuf, sizeof(WriteBuf));
// 关闭文件
file.Close();
// 只读方式打开文件
file.Open("C:\\TestFile.txt", CFile::modeRead);
while (true)
{
// 读取文件数据
int ret = file.Read(ReadBuf, 100);
……
// 如果到达文件结尾则中止循环
if (ret < 100)
break;
}
// 关闭文件
file.Close();

  Write()和Read()函数执行完后将自动移动文件指针,因此不必再显示调用Seek()函数去定位文件指针。包含有文件定位函数的完整代码如下所示:

// 创建、写入方式打开文件
CFile file;
file.Open("C:\\TestFile.txt", CFile::modeWrite | CFile::modeCreate);
// 写入文件
memset(WriteBuf, 'a', sizeof(WriteBuf));
file.SeekToBegin();
file.Write(WriteBuf, sizeof(WriteBuf));
// 关闭文件
file.Close();
// 只读方式打开文件
file.Open("C:\\TestFile.txt", CFile::modeRead);
while (true)
{
// 文件指针
static int position = 0;
// 移动文件指针
file.Seek(position, CFile::begin);
// 读取文件数据
int ret = file.Read(ReadBuf, 100);
position += ret;
……
// 如果到达文件结尾则中止循环
if (ret < 100)
break;
}
// 关闭文件
file.Close();

 

补充:

使用CFile类对文件进行按结构读取,如:

CFile fileRead,fileWrite;
 fileRead.Open(_T("E:\\a.dat"),CFile::modeRead);//这里使用宏_T
 fileWrite.Open(_T("E:\\backup.txt"),CFile::modeCreate | CFile::modeWrite);

VIDEOHEADER *videoheader=new VIDEOHEADER();
fileRead.Read(videoheader,sizeof(VIDEOHEADER));
char buf[sizeof(VIDEOHEADER)*8];
sprintf(buf,"videoheader.cCommandID:%s ,videoheader->cCommandID);通过sprintf对我们需要写入文件中的数据进行格式化,这样在文件中存储的数据就是以这里定义的格式显示的。
fileWrite.Write(buf,strlen(buf));