目录浏览及大文件在内存中的读写
来源:互联网 发布:淘宝怎么领取红包 编辑:程序博客网 时间:2024/06/08 04:42
通过一个MFC实例,将硬盘中的某个文件拷贝到另一个目标目录中,并用进度条显示拷贝进度。通过该实例熟悉以下3个应用:一是目录浏览窗口的使用;二是大型文件(占上百兆)的读写及传输;三是精确显示操作进度百分比。
(1)创建一个对话框类CFileCopyDlg及对话框,在上面显示三个按钮,分别是源文件浏览(IDC_ADD)、目标目录浏览(IDC_DEST)、拷贝(IDC_COPY)。再放两个编辑框控件IDC_EDADD和IDC_EDDEST,分别显示源文件全路径和目标目录全路径。
class CFileCopyDlg : public CDialog
{
...................
CString strname; //源文件名
CString fullname; //目标目录名
CString pathname; //源文件全路径名
HGLOBAL hGlobal; //
CFile* writefile; //写文件句柄
CFile* readfile; //读文件句柄
long readlen,poslen,filelen; //
LPVOID pvData; //分配的内存操作指针
CProgressCtrl m_fileproc;
....................
};
(2)源文件浏览按钮的操作
void CFileCopyDlg::OnAdd()
{
CFileDialog log(TRUE,"文件","*.*",OFN_HIDEREADONLY,"FILE(*.*)|*.*||",NULL);
if(log.DoModal()==IDOK)
{
pathname=log.GetPathName(); //保存源文件全路径名
strname=log.GetFileName(); //保存源文件名
GetDlgItem(IDC_EDADD)->SetWindowText(pathname);
}
}
(3)目标目录浏览按钮的操作
void CFileCopyDlg::OnPut()
{
if(strname.IsEmpty()) //如果没有选取任何文件,返回
return;
BROWSEINFO bi;
char buffer[MAX_PATH];
ZeroMemory(buffer,MAX_PATH);
bi.hwndOwner=GetSafeHwnd();
bi.pidlRoot=NULL;
bi.pszDisplayName=buffer;
bi.lpszTitle="选择一个文件夹"; //浏览窗口标题
bi.ulFlags=BIF_EDITBOX;
bi.lpfn=NULL;
bi.lParam=0;
bi.iImage=0;
LPITEMIDLIST pList=NULL; //浏览列表
if((pList=SHBrowseForFolder(&bi))!=NULL) //开始使用浏览窗口
{
char path[MAX_PATH];
ZeroMemory(path,MAX_PATH);
SHGetPathFromIDList(pList,path); //从列表中获得目录路径
fullname=path;
if(fullname.Right(1)!="\\") //如果路径名不带分隔符,需手工添加分隔符
fullname.Format("%s\\%s",path,strname); //将路径名跟文件名组合
else
fullname.Format("%s%s",path,strname);
GetDlgItem(IDC_EDDEST)->SetWindowText(fullname);
}
}
(4)拷贝按钮的操作
void CFileCopyDlg::OnCopy()
{
if(pathname.IsEmpty())
return;
if(fullname.IsEmpty()) //如果以上两个按钮都没有操作,就返回
return;
readfile=new CFile(pathname,CFile::modeRead); //读文件句柄赋值
HANDLE hfile=::CreateFile(fullname,GENERIC_WRITE|GENERIC_WRITE,0,0,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,0);
CloseHandle(hfile); //这两句防止重复使用时出现共享违例错误
writefile=new CFile(fullname,CFile::modeWrite); //写文件句柄赋值
filelen=readfile->GetLength(); //要读文件的文件长度,以字节为单位
ldiv_t r;
r=ldiv(filelen,100);
long pos=r.quot;
long ipos;
ipos=pos; //以100等分来分的话,每份要容纳pos个字节。也就是每传输pos个字节,进度条加1
int i=0; //进度条初始值和范围已设定
hGlobal = GlobalAlloc(GMEM_MOVEABLE,512);
pvData = GlobalLock(hGlobal);
while(1)
{
ZeroMemory(pvData,512);
readlen=readfile->ReadHuge(pvData,512); //实际读长度
poslen=readfile->GetPosition(); //相当于SEEK,移动文件指针,并返回已操作的长度
if(poslen>ipos) //如果已读长度大于等份累加长度
{
ipos+=pos; //变更等份累加长度
i++; //滑动条参数变更
}
m_fileproc.SetPos(i);
m_fileproc.Invalidate(); //设置并更新滑动条
writefile->WriteHuge(pvData,readlen); //将指针内容写入文件
if(poslen==filelen) //传输完就退出循环
break;
}
AfxMessageBox("复制完成");
m_fileproc.SetPos(0);
GlobalUnlock(hGlobal);
readfile->Close();
writefile->Close();
}
需要注意的是:大文件的传递和烧录等过程都是一个划分成小单位操作的循环过程,都是以较小内存缓冲区进行操作的。
- 目录浏览及大文件在内存中的读写
- android用NDK在内存卡创建目录、文件并进行读写操作
- 取得文件在内存中的位置(转贴)
- PE文件在内存中的加载
- 关于文件在内存中读写的问题
- SDCard文件读写与目录浏览 笔记
- 字符数据在内存中的存储形式及使用方法
- 值类型与引用类型及在内存中的存储
- 程序在内存中的分布及变量类型
- C/C++变量在内存中的位置及初始化问题
- 关于struct在内存中的存储结构及妙用
- C++类成员在内存中的存储及对齐方式
- 图像类型在内存中的标识--文件头
- 读写文件及创建目录
- 进程在内存中的影像
- 类在内存中的结构
- float在内存中的方式
- 负数在内存中的存储
- e.Handler的伟大神奇之处
- 异常总结
- silverlight中用代码动态控制Storyboard(动画)属性的几种方法
- WPF中的触发器简单总结
- hive安装配置
- 目录浏览及大文件在内存中的读写
- 在 Flex 应用程序中使用 AnyChart
- 在Style中将EventTrigger与Trigger同时使用
- JJTree
- silverlight 和 WPF 中的Storyboard和DependencyProperty的区别
- du and df 命令区别
- java 移动MAS的DB接口实现彩信发送
- Mysql中级联删除问题
- Windows phone 7 点滴 —— 性能问题