文件分割器Word文档下载推荐.docx
《文件分割器Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《文件分割器Word文档下载推荐.docx(40页珍藏版)》请在冰豆网上搜索。
4.3.文件选择模块22
4.3.1.类图22
4.3.2.源文件选择函数构造23
4.3.3.目标文件选择函数构造23
4.4.特色功能模块24
5.系统测试25
5.1.功能测试25
5.2.程序问题分析28
5.2.1.LR(0)分析程序工作的正确性28
5.2.2.LR(0)语法分析器的错误恢复策略28
5.3.程序的扩展性29
6.用户手册30
6.1.运行环境30
6.2.功能说明31
7.课程总结32
8.参考文献33
文件分割器(Filespliter)
1.绪论
1.1.课题内容
本设计主要是使用VisualC++6.0进行开发,通过面向对象分析和设计实现对文件的切割和合并操作,其中关键部分在于调用操作系统以及MFC提供的API函数,对进一步学习操作系统有重要意义。
1.2.依据的操作系统原理
操作系统的功能之一是对计算机系统的软件资源进行管理,而软件资源通常是以文件形式存放在磁盘或其它外部存储介质上的,对软件资源的管理是通过文件系统来实现的。
在计算机系统中,软件资源非常重要,对软件资源的使用也相当频繁,因此文件系统在操作系统中占有非常重要的地位。
文件系统具备的功能有:
实现文件的按名存取,分配和管理文件的存储空间,建立并维护文件目录,提供合适的文件存取方法,实现文件的共享与保护,提供用户使用文件的接口。
文件系统的层次模型如图1-1所示。
逻辑文件系统层
文件组织模块层
基本文件系统层
基本I/O控制层
图1-1文件系统的层次模型
本设计开发了在辅助进程中分割文件和合并文件的文件分割器,文件之所以能被分割,是与文件在计算机中存储方式密切相关的。
所有文件都以二进制的形式存储于介质(包括硬盘、软盘等外部存储器)中。
计算机在读取文件时,总是把数据转换成二进制形式,然后再根据文件系统的相应规定分别进行处理。
因此,所有文件都可以以二进制格式进行读写、分割,然后再以二进制的格式把分割后的文件重新合并起来。
2.需求分析
2.1.总述
为了方便用户使用文件系统,文件系统通常向用户提供各种调用接口。
用户通过这些接口来对文件进行各种操作。
对文件的操作可以分为两大类:
一类是对文件自身的操作,例如,建立文件,打开文件,关闭文件,读写文件,等等;
另一类是对记录的操作(最简单的记录可以是一个字符),例如,查找文件中的字符串,以及插入和删除,等等。
所谓文件的“打开”,是指系统将指名文件的属性(包括该文件在外存上的物理位置)从外存拷贝到内存打开文件表的一个表目中,并将该表目的编号(或称为索引)返回给用户。
以后,当用户再要求对该文件进行相应的操作时,便可利用系统所返回的索引号向系统提出操作请求。
系统这时便可直接利用该索引号到打开文件表中去查找,从而避免了对该文件的再次检索。
这样不仅节省了大量的检索开销,也显著地提高了对文件的操作速度。
如果用户已不再需要对该文件实施相应的操作时,可利用“关闭”(close)系统调用来关闭此文件,OS将会把该文件从打开文件表中的表目上删除掉。
文件分割器主要是为了解决实际生活中携带大文件的问题,由于存储介质容量的限制,大的文件往往不能够一下子拷贝到存储介质中,这只能通过分割程序把的文件分割多个可携带小文件,分步拷贝这些小文件,从而实现携带大文件的目的。
而合并器的作用则能够把这些分割的小文件重新合并,恢复原来的文件。
VisualC++6.0中提供的许多处理文件的类库,通过这些类能够简捷、灵活的实现对文件的操作。
2.2.程序功能要求
通过本学期对《操作系统》这门课程的学习,以及在操作系统的实验课上学到的理论知识和实践进行了这次《操作系统》的课程设计,这次课程设计主要完成对文件分割器的实现,该程序具有如下功能:
(1)源文件的浏览选择,采用对话框形式。
(2)目标文件夹的选择,同样采用对话框形式。
(3)文件分割操作。
(4)提供选择文件分割后是否删除源文件。
(5)文件合并操作。
(6)提供选择文件合并后是否删除源文件。
在实际工作中,经常会遇到一些比较大而自己非常需要的文件无法一次性地转存,或者在网络传输文件时无法一次性传输较大文件,这时就需要对文件进行分割,将大文件划分为多个较小的块,从而分次携带,最后再恢复。
本程序主要采用窗口类和控件组装成整个界面,内部对象和类均使用MFC基类所派生和构造,使整个设计过程更易于实现和操作。
3.系统设计
3.1.开发环境
开发平台:
WindowsXP+VisualC++6.0
开发使用框架:
MFCAppWizard(exe)-Dialogbased
开发语言:
C++
建立MFC界面过程如图2-1所示。
图2-1MFCAppWizard
3.2.总体设计
程序基于VisualC++6.0开发。
程序通过MFC向导建立后,VisualC++自动产生说明文件,即电子版根目录下的“ReadMe.txt”文本文件。
然后通过一步步建立程序控件、类以及相关对象实现整个程序的完成,采用面向对象方法进行控制和完善,实现起来简单明了,并在这一个过程中给出了各个类的说明,可以参见“ReadMe.txt”文本文件,也可以详见模块设计的类说明和构造过程以及实现的具体功能。
本程序的总体设计框架如图2-2所示。
它用来设置对文件分割操作或文件合并操作的选择、待分割(或合并)文件的路径以及所产生的文件的存放目录和其他参数。
当用户设置完成后,单击“分割”按钮或“合并”按钮,将会在对话框进度条中显示操作的进度。
文件分割操作将产生一系列与源文件相关的小文件,文件合并操作则能恢复原来的文件名。
因此,只要熟悉VisualC++环境中文件的操作,文件分割器的设计并不困难。
需要注意的是程序的组织,如多线程的实现,程序界面组织等。
图2-2系统总体设计框架
系统最终效果界面如图2-3所示。
图2-3系统效果图
3.3.模块设计
3.3.1.模块结构图
图2-4各个模块间的传递关系
3.3.2.模块说明
本程序主要分为四个模块:
源文件选择模块、目标文件夹选择模块、文件分割模块、文件合并模块。
源文件选择模块:
本模块与操作系统提供的API函数调用一致,只要对MFC或者WIN32有一定了解都可以很方便的设计出来。
staticcharBASED_CODEszSplitFilter[]=_T("
AllFiles(*.*)|*.*||"
);
staticcharBASED_CODEszMergeFilter[]=_T("
AllFiles(1_*.*)|1_*.*||"
由上面代码可以看到,本模块只提供文件的选择操作,并不限制文件类型的选择,这也就涉及到文件是二进制存储,不管什么类型的文件都可以进行分割、合并操作。
目标文件夹选择模块:
这个模块跟源文件选择模块类似,提供分割或者合并后文件的存放路径,这个路径和源文件选择的路径可以给我们提供对文件的存放操作。
具体操作如下:
CDirDialogdlg;
if(dlg.DoBrowse(this)==IDOK){
m_strTargetPath=dlg.m_strPath;
UpdateData(FALSE);
}
文件分割模块:
首先根据所要分割文件的文件名在指定目录下创建一个二进制文件,然后从待分割的文件中读取指定大小的数据存入该文件,接着在创建一个同样大小的以二进制方式写入的文件,并从上一次读取后的文件指针的位置处开始读取数据。
如此反复,直到待分割的文件的位置指针到达结束的位置。
这样就把一个大文件分割成了若干个小文件,并且各个小文件不仅保存了大文件的文件名信息,而且各个小文件的文件名之间也存在一定的联系。
这个模块是本程序的核心,它涉及文件分割的整个过程,包括文件分割算法,创建分割线程等。
为了能够在显示文件操作进度的对话框中显示操作的状态,分割文件和合并文件应该在辅助线程中完成。
文件合并模块:
根据某个目录下文件名的规律依次把各个小文件读入至一个新创建的大文件中。
这个模块在本程序设计中也是处于重要地位。
程序首先找到需要合并的源文件,其中关键的信息在于文件名的判别,通过序列的名字依次对每个分割文件进行合并,最终在目标文件夹下完成合并后文件的写入操作,实现文件的合并。
3.3.3.功能设计
(7)文件分割。
(8)文件合并。
(9)提供文件分割后删除源文件的选择。
(10)提供文件合并后删除源文件的选择。
(11)文件分割的进程提示,通过进度条方法。
(12)文件合并的进程提示,通过进度条方法。
3.3.4.界面设计
右上方提供源文件选择按钮,可以通过点击它实现对文件的浏览选择,具体设计如图3-1所示。
图3-1选择源文件
源文件的选择过程对话框的设计如图3-2所示。
图3-2源文件的选择过程
对目标文件目录的选择对话框的设计如图3-3所示。
图3-3目标文件夹的选择
文件分割进度条窗口设计如图3-4所示。
图3-4文件分割过程
4.系统实现
4.1.文件分割模块、合并模块
文件分割模块主要使用的类有CSplitFileDlg类、CSplitFileThread类、CSplitProgDlg类,与之关联的有CProgMergeDlg类,CMergeThread类,它们之间的关系如类图4-1所示。
图4-1文件分割模块类和其他类的关系
4.1.1.类说明
表4-1文件分割类说明表
名称
属性
说明
m_filename
数据成员
文件名
m_RatioSplit
分割文件选择按钮
m_checkMerge
合并后删除源文件按钮
m_sourcePath
源文件路径
m_checkSplit
m_targetBrowse
目标文件夹选择浏览
m_sourceBrowse
源文件选择浏览
m_strSource
存放源文件
m_strTargetPath
存放目标路径
m_split
分割操作
m_hlcon
图标变量
MergeFlie
成员方法
合并文件按钮
SplitFile
分割文件按钮
CSplitFileDlg
文件分割窗口
OnSysCommand
系统自定义函数
OnPaint
绘图函数
OnQueryDragIcon
查询icon图标函数
OnMergeratio
合并按钮选择操作
OnSplitratio
分割按钮选择操作
OnMerge
合并文件
OnTargetBrowse
目标文件夹选择操作
OnDestory
销毁对象
OnSplit
分割文件操作
OnSourceBrowse
源文件选择操作
4.1.2.文件操作
在VC++中进行文件操作,可以使用SDK函数,但更为简单的是使用MFC中的CFile类。
该类具有以下特点:
①:
CFileException类相结合,可以非常方便地处理操作异常。
②:
与Archive类结合使用,可以方便地实现文件的序列化。
下面讨论一下MFC中CFile类。
CFile类具有三种形式的构造函数,它们的原型如下:
CFile();
Cfile(inthFile);
③:
Cfile(LPCTSTRlpszFileName,UNITnOpenFlag);
第一个函数形式为默认的构造函数。
第二个函数形式用来将一个已经存在的文件与CFile对象相关联,参数为文件的句柄。
需要指出的是:
这里不检查文件的访问模式和类型,在释放CFile对象时不会自动关闭该文件,需要手动关闭。
第三个函数形式用来创建一个CFile对象并以指定的方式打开了一个指定路径的文件。
它实际上是使用默认构造函数构造CFile对象并调用CFile类成员函数Open两个步骤。
有关的函数操作将在介绍Open函数时详细讨论。
创建了CFile对象后,就可以对文件进行操作了。
1.打开文件
在进行其他操作之前,首先需要调用Open函数打开文件,该函数的原型为:
BOOLOpen(LPCTSTRlpszFileName,UNITnOpenFlag,CFileException*pError=NULL);
其中,参数lpszFileName用来指定待打开文件的路径名;
参数nOpenFlag表示共享和访问模式,它指定在文件打开后进行何种操作。
它可以是以下一个或几个取值的组合:
(1)CFile:
:
modeCreate:
创建一个文件。
若该文件已经存在,则将文件清空。
(2)CFile:
modeTruncate:
该值必须与CFile:
modeCreate一起使用,表示在创建一个文件时,若该文件已经存在,不将其清空,并且不管打开的文件是新建的还是已存在的,该文件都具有打开保护的属性。
(3)File:
modeRead:
打开文件并且其属性为只读。
(4)File:
modeWrite:
打开文件并且其属性为只写。
(5)CFile:
modeReadWrite:
打开文件并且其属性为可读可写。
(6)CFile:
modeNoInherit:
打开的文件不允许被子进程所继承。
(7)CFile:
shareDenyNone:
打开的文件不拒绝其他进程的读写。
若该文件正在被其他进程以兼容的方式访问,则文件打开失败。
(8)CFile:
shareDenyRead:
文件打开后拒绝其它进程进行读操作。
(9)CFile:
shareDenyWrite:
文件打开后拒绝其他进程进行写操作,若该文件正在被其他进程以兼容的方式访问,则文件打开失败。
(10)CFile:
shareExclusive:
文件打开后被该进程独占,拒绝其他进程对此文件进行访问。
若该文件正在被其他进程以任何读写方式打开,则文件打开失败。
(11)File:
shareCompact:
该标志不被32位MFC支持。
(12)CFile:
typeText:
以文本方式打开。
(13)CFile:
typeBinary:
以二进制方式打开。
参数pError用于指定接受打开操作错误的CFileException对象指针,若取NULL,则文件打开时不会产生异常。
否则会产生异常,从中可获得相应的错误信息。
2.读写文件
打开文件后,就可以调用Read和Write成员函数对文件进行读写操作了。
Read函数的原型如下:
UNITRead(void*ipBuf,UNITnCount);
其中,参数lpBuf是接收读取数据的缓冲区的指针:
参数nCount用来指定读取文件的最大字节数。
函数返回实际读取的字节数。
Write函数的原型如下:
UNITRead(constvoid*ipBuf,UNITnCount);
其中,参数lpBuf是保存待写入数据缓冲区的指针;
参数nCount为数据的最大写入字节数。
Write函数返回实际写入的字节数。
需要指出的是,Read和Write函数最大只能读写64KB的数据。
为此CFile类提供了ReadHuge和WriteHuge函数用来读写大型文件。
这两个函数与上述的Read和Write函数类似,在此不再赘述。
3.动文件位置指针
CFile类提供了一系列成员函数来控制文件位置指针的移动。
其中,SeekToBegin和SeekToEnd用来将文件指针移至文件的开头和结尾部分。
而Seek函数可以将指针移至文件中的指定位置,该函数原型为:
LONGseek(LONGlOff,UINTnFrom);
参数lOff用来指定指针移动的字节数;
参数nFrom用来指定移动的初始位置,它可以取如下值:
(1)File:
begin:
从文件开始处向后移动lOff字节。
current:
从文件当前位置移动lOff字节。
(3)CFile:
end:
从文件结束位置向前移动lOff字节,此处的lOff应为负数。
4.1.3.编程思路和步骤
1.文件分割器的编程思路
文件之所以能被分割,是与文件在计算机中存储方式密切相关的。
分割文件的具体方法是:
合并文件的方法是:
2.文件分割器的编程步骤
(1)编辑应用程序对话框模板。
如图所示为编辑对话框模板IDD_FILESPITTER_DIALOG。
(2)向主对话框类添加成员变量。
在主对话框类中添加与对话框模板控件相关联的成员变量和其他附加变量,如表4-2所示。
(3)创建用于分割文件和合并文件的线程类。
为此需要创建用于分割文件和合并文件的线程类CSplitThread和CMergeThread。
它们派生自CWinThread类。
表4-2主对话框类说明表
控件ID
变量类型
对应变量
变量功能
IDC_MERGECHECK
CButton
合并后删除
IDC_SOURCE_BROWSE
m_sourcebrowse
被分割文件选择
IDC_SOURCEPATH
CString
m_strSourcePath
被分割文件的路径
CEdit
编辑路径
IDC_SPLITCHECK
分割后删除
IDC_SPLITRADIO
m_RadioSplit
分割文件
IDC_TARGER_BROWSE
目标文件选择
IDC_TARGERPATH
目标文件路径
无
BOOL
m_bSplit
分割/合并文件
m_strFileName
源文件文件名
4.2.分割、合并线程模块
线程模块分为分割文件线程和合并文件线程,创建了用于分割文件和合并文件的线程类,即线程类CSplitThread和CMergeThread。
4.2.1.类图
图4-2分割线程类类图
图4-3合并线程类类图
4.2.2.算法分析与设计
创建用于分割文件和合并文件的线程类。
其中,类CSplitThread定义如下:
classCSplitProgDlg;
classCSplitThread:
publicCWinThread
{
public:
DECLARE_DYNAMIC(CSplitThread)
CSplitThread(CSplitProgDlg*pWnd);
virtual~CSplitThread();
//Attributes
//Operations
//Overrides
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CSplitThread)
public:
virtualBOOLInitInstance();
virtualintExitInstance();
//}}AFX_VIRTUAL
//Implementation
intm_len;
BOOLm_bErrResult;
CSplitProgDlg*m_pDlg;
//Generatedmessagemapfunctions
//{{AFX_MSG(CSplitThread)
//NOTE-theClassWizardwilladdandremovememberfunctionshere.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
protected:
BOOLm_check;
voidSplitFile();
};
由于该进程将文件分割进度对话框CSplitProgDlg启动和终止,因此,应当有CSplitProgDlg类的成员变量m_pDlg来建立它们之间的联系。
成员变量m_len和m_check分别表示文件分割成多少文件以及分割完成后是否删除源文件。
成员变量m_bErrResult用来表示操作的错误信息。
当分割文件启动时,该线程类的InitInstance函数将调用成员函数SpliF