文件的合并与拆分

最近编写了一个小工具,实现文件的合并与拆分,依然是使用的MFC,在编写工具过程中,基本把涉及到的文件与文件夹的操作 都过了一遍,同时涉及到MFC中 “Tab Contorl” “Combo Box” “List Box” 以及 "Check Box" 的使用,对于一些常见的问题解决方法在这里做一个小小的总结。

Part 2:文件合并与拆分
选择文件
//用于存放文件名
CString fileName;
//文件过滤器(只显示我们想要格式的文件)
char* filters = _T("视频文件(*.txt)|*.txt");
//创建一个可以选择多个文件的CFileDialog
CFileDialog fileDlg(true,NULL,"*.txt",
OFN_ALLOWMULTISELECT | OFN_ENABLESIZING |
OFN_HIDEREADONLY,filters);
//最多可以打开50个文件
fileDlg.m_ofn.nMaxFile = 50 * MAX_PATH;
char* ch = new TCHAR[fileDlg.m_ofn.nMaxFile];
fileDlg.m_ofn.lpstrFile = ch;
//对内存块清零
ZeroMemory(fileDlg.m_ofn.lpstrFile,sizeof(TCHAR) * fileDlg.m_ofn.nMaxFile);
//打开文件对话框,用户选择之后,获得文件名集合
if(fileDlg.DoModal() == IDOK)
{
//获取第一个文件的位置
POSITION pos_file;
pos_file = fileDlg.GetStartPosition();
//读出每个路径并存放在数组中
while(pos_file != NULL)
{
//将文件路径增加至字符串末尾,以空格分隔,在这里也可以定义一个数组存放
fileName = fileDlg.GetNextPathName(pos_file);
fileName += " ";
m_filename.Add(fileName);
}
fileName=fileName.Left(fileName.GetLength()-1); //去掉最后一个空格
}
delete[] ch;
使用这种方式可以支持多文件的选择,下面还有一种简单的方法进行单个文件的选择。
//定义CString变量用于存放获取的文件名
CString fileName = _T("");
//创建一个CFileDialog
CFileDialog dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY,
_T("Describe Files (*.zv)|*.zv|All Files (*.*)|*.*||"), NULL);
//打开文件对话框,用户选择之后,获得文件名
if (dlgFile.DoModal())
{
fileName = dlgFile.GetPathName();
}
选择目录
char szPath[MAX_PATH]; //存放选择的目录路径
CString CatalogName; //定义字符串存放最终的目录
//内存块清零
ZeroMemory(szPath, sizeof(szPath));
//定义弹出的选择目录窗口
BROWSEINFO bi;
//进行初始化
bi.hwndOwner = m_hWnd;
bi.pidlRoot = NULL;
bi.pszDisplayName = szPath;
bi.lpszTitle = "请选择文件目录:";
bi.ulFlags = 0;
bi.lpfn = NULL;
bi.lParam = 0;
bi.iImage = 0;
//弹出选择目录对话框
LPITEMIDLIST lp = SHBrowseForFolder(&bi);
if(lp && SHGetPathFromIDList(lp, szPath)) //将获取到的路径存放至szPath
{
//转换成CString格式的字符串
CatalogName.Format("%s",szPath);
}
以上2个功能是文件读写的前置操作,下面介绍正题。
文件合并
文件合并的流程是:
以读的方式打开N个老文件;
以写的方式打开新文件;(新,老文件打开顺序可变)
将读出的数据依次写到新文件末尾;
保存。
FILE * newfile, * oldfile; //定义“新”,“老”文件
CString fileName = "new.txt"; //默认打开的文件名
CString filter = "(*..txt)|*..txt||"; //文件过虑的类型
//弹出保存文件对话框
CFileDialog openFileDlg(FALSE,"",fileName,
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, filter, NULL);
if(openFileDlg.DoModal() == IDOK)
{
//获取用户填写的新文件名
CString check = openFileDlg.GetPathName();
//以“写”方式打开
newfile = fopen(check,"wb");
if( newfile == NULL)
{
AfxMessageBox("新文件创建失败");
}
//自己定义了一个文件列表,读取到每一个文件,依次写入
for (int i = 0;i<count;i++)
{
//文件名称临时变量
CString oldfilenametemp;
//获取文件名
m_myfilelist->GetText(i,oldfilenametemp);
//以“读”的方式打开
oldfile = fopen(oldfilenametemp,"rb");
//定义char型数组存放数据,MAXLEN是我自己定义的宏,长度为512*1024
unsigned char buf[MAXLEN];
//存放结果,如果读取文件成功,返回真正读取到的字节数
int rc;
//只要文件没有结束,一直读
while( (rc = fread(buf,sizeof(unsigned char), MAXLEN,oldfile)) != 0 )
{
//将读取的内容写到新文件的末尾
fwrite( buf, sizeof( unsigned char ), rc, newfile );
}
}
//关闭文件
fclose(oldfile);
fclose(newfile);
AfxMessageBox("合并成功");
文件拆分
文件拆分的流程是:
确定拆分出的文件大小;
打开一个老文件,读取内容;
每读到规定文件大小的内容就停止,保存为一个新文件,直到文件被全部读完;
//定义老文件
FILE * oldfile;
//定义文件长度
int oldfilelen = 0,newfilelen = 0;
//以“读”方式打开指定“oldfilepath”路径的文件
oldfile = fopen(oldfilepath,"rb");
fseek(oldfile,0,SEEK_END); //将源文件定位到文件尾
oldfilelen = ftell(oldfile); //获取文件长度
if(oldfile == NULL)
{
AfxMessageBox("文件打开失败");
}
// size为 XXX MB,转换成byte即为子文件长度
newfilelen = size*1048576;
//拆分得到的文件个数就是 “旧文件大小/新文件大小”
int num = ceil((double)(oldfilelen/newfilelen))+1;
for (int i = 0;i<num;i++)
{
FILE * newfile; //定义新文件
//以“写”方式打开指定“path”路径的文件(其实就是新文件的保存路径)
newfile = fopen(path,"wb");
//定义拆分文件长度的char型缓冲区
unsigned char * buf = new unsigned char[newfilelen];
//读取结果
int rc;
//从旧文件读出固定长度,存放到buf
oldfile = fopen(oldfilepath,"rb");
//设置偏移量
long offset = i * newfilelen;
//进行偏移
fseek(oldfile,offset,SEEK_SET);
rc = fread(buf,sizeof(unsigned char),newfilelen,oldfile);
//写入新文件中
fwrite( buf, sizeof( unsigned char ), rc, newfile );
//关闭新文件
fclose(newfile);
}
//拆分完成之后关闭老文件
fclose(oldfile);
AfxMessageBox("拆分成功");






整合FileDisk和Filemon的MFC开源码,希望对新手有帮助! 说明:对大侠们可能没什么价值,仅以此献给像我一样的菜鸟! 软件环境和框架: 1.软件环境:VS.net2003 + XP IFS + DS3.2 2.框架:采用MFC框架; 功能: 1.自动加载FileDisk和Filemon的驱动程序部分; 2.用FileDisk生成一个虚拟硬盘,并自动分配盘符; 3.对新生成的虚拟盘符挂接Filemon的过滤驱动; 4.退出时自动卸载FileDisk和Filemon驱动; 不完善的地方(有兴趣的朋友可以完善下,并希望完善后请在我这里跟帖上传源码,就算是对我开源的支持,谢谢!): 1.FileDisk生成的虚拟硬盘需要先手动在资源管理器里进行格式化;可以在程序里调用SHFormat之类的启动格式化窗口进行改善,也可以使用第三方提供的格式化函数进行格式化; 2.Filemon目前是应用程序使用按照时间来进行查询的过滤方式,希望能改成驱动程序主动通知应用程序。 ------- 整理后面的回贴后追加的内容 ---------------- 1.在BOOL CMainFrame::Init(void)函数里有段网络通讯的代码,里面访问了我自己建的局域网服务器,大家那里应该是没有的,所以会报错,不好意思!注释或删掉以下内容就好了! CWebWrapper clsWebWrapper; CHttpDataPackage_Receive HttpData_Receive; //Call server function if (clsWebWrapper.PostCommand( _T(""), _T("abcd我你他"), &HttpData_Receive, _T("WebGrab"), this, FALSE, FALSE)) //if (clsWebWrapper.GetCommand( _T(""), _T("abcd我你他"), &HttpData_Receive, // _T("WebGrab"), this, FALSE, FALSE)) { AfxMessageBox(HttpData_Receive.GetContent_DataAll()); } else { AfxMessageBox("网络通讯失败"); return FALSE; } 2.大家如果想看文件过滤出来的信息,可以在BOOL CMainFrame::Init(void)函数里去掉对这句话//m_nTimer = SetTimer( 1, 500/*ms*/, NULL );的注释,那就相当于启动了定时器,然后会有信息显示在子窗口里,,当然我并没有去实现子窗口的滚动,所以子窗口里的内容满了后,就看不到最新的信息了,,哈哈,,我实在是没时间啊,,公司里的项目这2天在出演示版呢,,,忙啊。。。。大家自己加加代码哈,,,这也是个不完善的地方,希望完善了的朋友,,上传下代码啊,,,多谢! 3.另外,请下载使用了的朋友,有空的话来帮忙说下使用上有没有问题啊,如果有问题,我好及时做修改啊,谢谢了!如果可以用的话,有空就帮忙回个贴,说可以用,这样别的朋友就知道这个代码是可以用的,免得大家还以为下了个不能用的东东,那不是郁闷死了!先谢谢了! ------------- 最新补充说明 ------------------- 1.FileDisk和Filemon我用的都是比较老的版本了,FileDisk是2004年的,Filemon是4.34 ;FileDisk的作者在其网站上已经出了新版本了,是2006年的,我下载了,还没时间看过,所以大家有空也可以整合2006的驱动来替换我的老版本,毕竟老版本是可能有些不完善的地方的;而Filemon则没有再继续开放源码,,所以如果有朋友有幸获得了新版本的源码,能不能上传个,,多谢了! 2.Filemon.exe会自动在其目录下创建File.img文件做为虚拟磁盘使用的文件,大家只要手动格式化一次创建出来的虚拟磁盘,以后就不用再格式化,可以不断使用了,所以以后大家要是做成产品的话,可以直接把已经格式化好的对应的File.img文件一起打包到安装包里,呵呵! 3.我放弃了FileDisk中对CDROM部分的支持,以及Filemon中对Win9x的VxD驱动的支持,如果有朋友需要的话,可以自行添加!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值