拷贝文件假死

yingbinchina 2012-11-26 10:37:44
测试发现:
拷贝一个282M的文件需要82秒,使用的是CopyFile函数。而且这时,程序假死,界面的按钮无法被点击。
很着急想解决这个问题。
采用分块拷贝的方法,写函数如下。用时496毫秒。看来不好。
请大牛支招。可以快速的拷贝文件,而且可以不假死,鼠标等操作保持流畅。而且满足随时结束拷贝的过程。谢谢!

void CToolsDlg::OnBnClickedButton4()
{
// TODO: Add your control notification handler code here
CString strSrc, strDest;
GetDlgItem( IDC_EDIT2 )->GetWindowText( strSrc );
GetDlgItem( IDC_EDIT3 )->GetWindowText( strDest );

DWORD dwTime1 = GetTickCount();

int nEachSize = 1024 * 8;
HANDLE hSrc = CreateFile( strSrc, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if ( hSrc == INVALID_HANDLE_VALUE )
{
ASSERT( FALSE ); return;
}
HANDLE hDest = CreateFile( strDest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL );
if ( hDest == INVALID_HANDLE_VALUE )
{
ASSERT(FALSE); return;
}
DWORD dwFileSize = GetFileSize( hSrc,NULL );
BYTE* pBuf = NULL;
pBuf = new BYTE[nEachSize];
if ( pBuf == NULL )
{
ASSERT( FALSE ); return;
}
int nCopyCount = dwFileSize / nEachSize;
DWORD dwReaded;
for ( int i=0;i<nCopyCount;i++ )
{
if(!ReadFile( hSrc, pBuf, nEachSize, &dwReaded, NULL ))
{
ASSERT(FALSE); return;
}
if ( !WriteFile( hDest, pBuf, nEachSize, &dwReaded, NULL ))
{
ASSERT(FALSE);return;
}
}
int nLeftByte = dwFileSize - nCopyCount*nEachSize;
if(!ReadFile( hSrc, pBuf, nLeftByte, &dwReaded, NULL ))
{
ASSERT(FALSE); return;
}
if ( !WriteFile( hDest, pBuf, nLeftByte, &dwReaded, NULL ))
{
ASSERT(FALSE);return;
}

CloseHandle( hSrc );
CloseHandle( hDest );

DWORD dwTime2 = GetTickCount();
DWORD dwCost = dwTime2 - dwTime1;
DWORD dwSec = dwCost / 1000;
CString strTimeCost;
strTimeCost.Format(_T("%d"), dwSec );
GetDlgItem( IDC_ShowTime )->SetWindowText(strTimeCost);
UpdateData(FALSE);
}
...全文
434 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
baoyz 2012-12-02
  • 打赏
  • 举报
回复
1、把工作放入线程 2、线程中建两个FILE*,一个用于读文件,一个用于写文件。 3、开一个循环,循环的条件是"线程开关变量" && EOF。 4、读文件1024*N个字节,再写入新文件。 ……
yingbinchina 2012-11-29
  • 打赏
  • 举报
回复
在拷贝一个300M的文件时,子线程也在COPYFILE函数中,like this: CopyFile( File是300M ); //这时候用户点击取消拷贝,没有响应了。因为CopyFile没有返回,还在运行。也就是拷贝的粒度是单个文件。 如何随时结束拷贝这么大的文件呢?
ls443085074 2012-11-29
  • 打赏
  • 举报
回复
用户线程阻塞了。把拷贝工作新建个线程里面去做,按钮操作是在用户线程里面的
yingbinchina 2012-11-29
  • 打赏
  • 举报
回复
TerminateThread来关闭线程,是不是不太安全?
傻X 2012-11-29
  • 打赏
  • 举报
回复
引用 10 楼 yingbinchina 的回复:
问题点: 不管是在主线程拷贝,还是在子线程中拷贝。都希望用户可以随时结束拷贝任务。如果文件很大的时候,用户如何随时结束拷贝呢?是采用分块拷贝吧?可是分块的耗时太多。这个问题成了博弈?
你如果自建线程调用COPYFILE的API拷贝的话,TerminateThread是可以的,且不会造成内存泄露。 另外你用System("XCOPY")的方法,出现控制台界面,也可以,此方法也不会有内存泄露
Eleven 2012-11-29
  • 打赏
  • 举报
回复
多线程,在工作线程中实现copy操作~
schlafenhamster 2012-11-29
  • 打赏
  • 举报
回复
试试 CopyFileEx
这不是鸭头 2012-11-29
  • 打赏
  • 举报
回复
界面主线程里拷贝到原因。另开启一个线程,在线程里拷贝
钟球盛 2012-11-28
  • 打赏
  • 举报
回复
1、主线程负责显示,辅助线程用于拷贝;
钟球盛 2012-11-28
  • 打赏
  • 举报
回复
方法:1、主线程负责显示,辅助线程用于显示; 2、定义一个无模式对话框用于随时结束拷贝任务,这创建这个无模式对话框实例化对象时,要把当前窗 口的指针传给这个对象;使得这个对话框跟主窗口共存亡。这是这个对话框窗口就具备了窗口的属性,可发消息; 3、当用户需要结束拷贝任务时,通过点击无模式对话框中的按钮消息响应函数,该函数主View窗口发送自定义的窗口消息,主窗口接受到消息后,进行响应的操作并结束拷贝。 这样就实现了窗口不假死,并可随时结束或启动任何任务; 知识点:A:作者需要知道无模式对话框的使用方法! B:自定义消息的使用方法; C:需要知道消息机制; 祝你早日解决问题!!
yingbinchina 2012-11-28
  • 打赏
  • 举报
回复
问题点: 不管是在主线程拷贝,还是在子线程中拷贝。都希望用户可以随时结束拷贝任务。如果文件很大的时候,用户如何随时结束拷贝呢?是采用分块拷贝吧?可是分块的耗时太多。这个问题成了博弈?
傻X 2012-11-27
  • 打赏
  • 举报
回复
两种方法。 1.拷贝放新线程 2.主界面拷贝,卡死,起新线程显示进度条。 我们2种方法都用,应为项目需要
schlafenhamster 2012-11-27
  • 打赏
  • 举报
回复
for ( int i=0;i<nCopyCount;i++ ) {// 加 peekmessage
酷爱冰红茶 2012-11-27
  • 打赏
  • 举报
回复
引用 6 楼 fengqinqdca 的回复:
1.拷贝文件可以开个线程.. 2.我是来学习下怎么快速拷贝文件的.
这个貌似就是算法的问题了吧!Windows的应该是快的了吧!你要是研究出个比它快的应该可以卖很多钱!
华美乐章 2012-11-27
  • 打赏
  • 举报
回复
1.拷贝文件可以开个线程.. 2.我是来学习下怎么快速拷贝文件的.
酷爱冰红茶 2012-11-27
  • 打赏
  • 举报
回复
把拷贝的过程放到线程中就好了!我正在实习中,做了个练习就是模拟Windows资源管理器的,其中复制过程就涉及到多线程,多文件的拷贝和进程间通讯问题,你需要代码的话可以加我QQ:634550666 要么回复我邮箱,我发给你,你做参考下!
lilianjie001 2012-11-26
  • 打赏
  • 举报
回复
引用 1 楼 jiuchang 的回复:可以启动一个工作线程来实现拷贝的功能,这样不影响主线程 引用 2 楼 jason_wentzel 的回复:放到线程中去做 拷贝一个282M的文件需要82秒,在主线程中肯定是把界面卡死了,不可以放在主线程中的。
九州剑王 2012-11-26
  • 打赏
  • 举报
回复
引用 1 楼 jiuchang 的回复:
可以启动一个工作线程来实现拷贝的功能,这样不影响主线程
引用 2 楼 jason_wentzel 的回复:
放到线程中去做
+1 楼主在主线程里,当然要搞得你程序像死掉一样的了。。。
孤客天涯 2012-11-26
  • 打赏
  • 举报
回复
放到线程中去做
jiuchang 2012-11-26
  • 打赏
  • 举报
回复
可以启动一个工作线程来实现拷贝的功能,这样不影响主线程

679

社区成员

发帖
与我相关
我的任务
社区描述
智能路由器通常具有独立的操作系统,包括OpenWRT、eCos、VxWorks等,可以由用户自行安装各种应用,实现网络和设备的智能化管理。
linuxpython 技术论坛(原bbs)
社区管理员
  • 智能路由器社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧