怎么拷贝含很多文件的文件夹才快!!!!!!!

时间:2022-07-11 21:39:40
我用FSO vb自带的filecopy  api的copyfile SHFileOperation等都试过,速度都不理想,SHFileOperation最慢.如果文件夹里文件数量多或有百兆以上的大文件,程序就跟死了似的,虽然加了doevents也没有什么作用.看CPU占用倒不会超过50%,但电脑的反应变得明显慢了.

我要拷贝的东西,有子目录,有文件. 我把这些要拷贝的文件名字和路径都预先存放到一个集合里了.然后for each .....next 从集合里取出名字路径去拷贝.判断是文件夹的就fso.copyfolder 判断是文件的就FSO.copyfile .不存在拷贝不成功的问题,就是遇到我上面说的情况的时候,程序反应跟死了似的,等拷贝完成后,就一切恢复正常了.虽然我在for each .....next里用了doevents,好像没有任何帮助.文件数量少或文件小的话,基本一切正常.
我拷贝一个759M大小的目录的内容到同一分区的另一目录, 文件数量4831个,子文件夹222个,其中最大的文件285M,最小的文件1K,整个拷贝用时100秒.太慢了.用系统自己的复制粘贴也才120秒. 但好像系统的复制粘贴占用CPU比较大.

哪位大虾能告诉我,怎么才能处理好我这种情况的拷贝? 主要是提速,以及不让程序假死.

25 个解决方案

#1


如果文件很大,手动拷也要几分钟嘛。

#2


这是因为调用的是外部函数,你的doevents,无法插入到Copy过程中,文件又多又大,VB自然就锁死,就象SQL查询大数据库一样,查询过程中你只能等。

要想能完全控制过程,Copy函数就要自己写。

#3


这个问题涉及到操作系统底层了。要从根本上加快比较难。如果不想直接干预磁盘操作(现在的 Windows,想直接干预也难),也只能略尽人事而已:

1 尽可能关闭其他程序,Copy 程序本身也要尽量少占内存空间,以便使用更大的内存缓冲区,减少磁盘往复读写的次数。
2 经常整理磁盘,不使其存在太多碎片。从这些旮旯里把文件抠出来,再塞到另一写缝隙里去,效率可想而知。

#4


速度问题我想不是很好解决,这个是客观存在的,优化作用不大。
不让程序假死的话,你可以调用以下api,显示文件拷贝的进度条
Private Declare Function SHFileOperation Lib _
"shell32.dll" Alias "SHFileOperationA" (lpFileOp _
As SHFILEOPSTRUCT) As Long

#5


同意楼上的说法,起码让界面看起来比较实际点,否则还没完成等待就已经闷死了。

#6


调用dos下命令!

#7


自己开一个线程不要让自己主界面死掉就行了,速度不可能快的,不可能你写的程序比微软自带还快的

#8


如果我把这样的拷贝放到局域网里进行,是用winsock来发送好呢,还是直接拷贝快! 不过直接拷贝容易把局域网的带宽占用完了,多台工作站去拷贝一台服务器的目录,也容易把服务器拷贝得慢如蜗牛.....但是象这么复杂的目录用winsock来传送好像太烦琐了,不太现实.

看到网上有些网吧游戏更新程序,用一个服务器做目录,然后让下面的工作站去比较更新. 目录和文件进行比较倒是很容易也很快,这我也能办到. 但接下来的拷贝是怎么做的呢. 网络带宽以及服务器的磁盘承受能力, 用winsock去发送这么复杂的文件夹文件,想都不用想,何况工作站不止一台呢?

哪位能给个思路. 局域网一台服务器上的一个目录(含子目录),N台工作站里的同一目录,同时对服务器上的这个目录进行文件(夹)比较,发现服务器的目录内容有变化,就把更新的内容复制到本地的相对目录来.
目录内容更新比较很容易,更新拷贝从原理也很简单,但情况就象我1楼帖子说的那样. 现在我没有用winsock来做,主要考虑文件夹的复杂性,用winsock传输太麻烦了,而且,如果用tcp传输又没有广播功能,用UDP广播,可靠性不够.

不知道高手们要解决局域网上目录更新,1台服务器对多台工作站的方式,会采用什么思路呢?

#9


在局域网内,有共享条件,当然不要用winsock,为减小占用与重复操作,
1、你应在服务端用程序自动建一个所有相关或最新文件列表
2、客户端下载列表自己分析需更新文件,分别自建需更新文件的列表,再下载文件
3、若局域网客户机也可互相访问,你还可仿照BT的方式,由不同客户机分担不同文件夹段的更新,这只需在服务器列表中指明位置就行了,也容易实现。

#10


谢谢homezj(小吉) 

我目前就做的你说的 1 2两个步骤.
第3个步骤是个好方法,不会呀,能把第3步骤的思路给得再明确些吗?

呵呵,真有意思,我在csdn上就提过3个问题,全部是你解答的.哈哈,谢谢.

#11


我这样考虑,做个服务端,当一台工作站更新完成后,就给服务端发送一个消息,告诉服务器,它已经更新完毕了.服务器把这个工作站的一些信息记录下来. 每个客户端要更新前都先给服务器发送一个请求,服务器如果有记录就告诉这个工作站,到另外一个已经更新过的工作站去比较更新去.同时删除掉这个记录,如果服务器没有已经更新过的工作站的记录,就自己承担提过更新的任务. 

这样做,服务器减轻了一点压力,不如你说的不同工作站分段更新来得好,但是编程方面就容易多了.因为下面的工作站重启关机没有任何规律,我无法把分段的任务明确分配给哪台工作站.

#12


想想还是不行,应该学BT的方法. BT是什么方面呢?:)

#13


按某种方法排序,然后分段,分配给各工作站,各工作站自己负责的段作为服务器来给别人服务

#14


工作站如果关机,无法提供服务,工作由服务器来完成

#15


还要动用BT技术啊...这个复制可真是经典了!

#16


是呀,网络复制得考虑网络带宽的占用,以及被拷贝磁盘的压力问题. 采用分段比较拷贝,对减轻服务器压力,增加拷贝速度确实很重要.要不你试试,弄多台工作站去拷贝你服务器,你服务器会慢如蜗牛.

还有种想法,把服务器做成FTP,工作站比较文件后更新下载. 那些ftp服务器可以同时承受那么多下载任务,应该比直接拷贝承受力强些.

#17


呵呵,这么巧,都是我答的,我还没注意,有缘呀!
前面我想的也只是思路,没实际做过,不敢乱说。

FTP也好,HTTP也好,我觉得都可满足,只是速度与效率问题。

我想得没你说的那么复杂,我甚至认为可以不做专门服务器程序,不用进行通讯,只是将总列表放在服务器一个共享路径下(当然是只读的),每个下载过的机器,都在另一个可写的路径下,留下一个自己下载内容的列表,客户机先在这些列表中搜索是否有客户机可用,若没有或尝试连接不能访问,再去找总列表下的服务器位置去复制。

我不了解你们局域网的特定环境,我想肯定是交换机啦,要是HUB那就不要想分享方式了^_^。

#18


我遇到过类似问题,其实把部分小文件通过调用外部命令压缩后传输要快很多。可以做个判断,文件小于多少的全压缩到一个文件(如果太多的话压一个),楼主试试效果应该有的,我以前用过

#19


不过说实话...BT技术不会有助你这样的应用!
因为宽带是你的,机器与机器之间通道都这么宽.怎么BT也不能把这样的通道扩宽!
另外,在"BT"中还有很多很多的信息交换.不但没有助益,还会成为拖累!
如果你是因为不可以让一台机器占用过多的带宽,你可以考虑限流:实现平均分配带宽!
这样的话,建议用Sock来搞!这样就不是单单的复制这么简单了!

另外,VB+Winsock请不要过份的幻想这对组合!
然而也不是不能.但对于这么做之后,就不是拷贝文件了.而是同步数据!也就不符合这贴子的主题了.不作评论,见谅

#20


这样:
Private Sub Command1_Click()
    Shell "xcopy D:\xxx\*.* c:\yyy\*.* /s"
End Sub


如果不想让用户看到copy过程,就这样:
Private Sub Command1_Click()
    Shell "xcopy D:\xxx\*.* c:\yyy\*.* /s", vbHide
End Sub

#21


没看清问题就回复了,抱歉。
个人人为BT的思想可行。但是必须是你的局域网是交换机而不是HUB。否则BT的方式只会给你添麻烦。
BT的思想基本上就是让你的服务器尽可能的充当一个列表的功能。
就像这样:

服务器:“嘿嘿,我更新了文件,谁要?来我这里找!”
客户1:“我要文件A!”
服务器:“客户1,准备接收!其他人等一等!”
客户1:“文件A接受完毕!”

服务器:“OK!现在我空闲,谁还要文件?”
客户2:“我要文件B!”
服务器:“客户2,准备接收!其他人等一等!”
客户2:“文件B接受完毕!”

服务器:“OK!现在我空闲,谁还要文件?”
客户3:“我要文件A!”
服务器:“客户3,你要的文件在客户1那里,你去找他要!”
客户3(跑到一边去自己跟客户1商量):“客户1,我要文件A!” ……

服务器:“现在我空闲,谁还要文件?”
……
……

#22


真是受益非浅

#23


我晕~这也叫"BT"!好心啰~~!pfpf

#24


呵呵,只有用winsock来限制流量,但面对复杂的目录结构,用sock来传输处理起来太麻烦了.真有点佩服那些做网吧游戏更新软件的人了.他们怎么做的.

网吧里的网络游戏种类众多,最常用的也有几十个. 每个游戏目录小则数百兆,大则几个G.而且目录结构也挺复杂的.子目录数量很多.并且这些游戏几乎天天都需要更新才能玩. 网吧的工作站一般都安装有还原软件或硬件,重启就还原. 他们就用一台不还原的机器,安装那几十个游戏,定时去更新这些游戏.那些工作站开机后自动去跟这台游戏服务器去比较游戏的差异文件,然后把更新过的文件拷贝过来. 天,这些网吧一般有几十上百台电脑,普通的百兆交换机而已,这种更新可以在网吧正常营业的情况下进行,不影响那些正在玩游戏的人,怎么做到的?????

这类游戏更新软件,分客户端和服务端. 通过服务端来安排哪些工作站开机后更新哪些游戏. 客户端就只需要输入服务端的IP就可以了. 千万别以为是什么商业软件,不少这类软件都是业余写手写的.

#25


你所说的网吧客户机根本不需要复制几个G的文件。通常有一个类似浏览器的管理程序,只需要按游戏列表显示图标和名称;点击了改图标后,如果没有下载,就下载该游戏,否则就直接运行。在局域网用共享目录复制文件不会很慢。

#1


如果文件很大,手动拷也要几分钟嘛。

#2


这是因为调用的是外部函数,你的doevents,无法插入到Copy过程中,文件又多又大,VB自然就锁死,就象SQL查询大数据库一样,查询过程中你只能等。

要想能完全控制过程,Copy函数就要自己写。

#3


这个问题涉及到操作系统底层了。要从根本上加快比较难。如果不想直接干预磁盘操作(现在的 Windows,想直接干预也难),也只能略尽人事而已:

1 尽可能关闭其他程序,Copy 程序本身也要尽量少占内存空间,以便使用更大的内存缓冲区,减少磁盘往复读写的次数。
2 经常整理磁盘,不使其存在太多碎片。从这些旮旯里把文件抠出来,再塞到另一写缝隙里去,效率可想而知。

#4


速度问题我想不是很好解决,这个是客观存在的,优化作用不大。
不让程序假死的话,你可以调用以下api,显示文件拷贝的进度条
Private Declare Function SHFileOperation Lib _
"shell32.dll" Alias "SHFileOperationA" (lpFileOp _
As SHFILEOPSTRUCT) As Long

#5


同意楼上的说法,起码让界面看起来比较实际点,否则还没完成等待就已经闷死了。

#6


调用dos下命令!

#7


自己开一个线程不要让自己主界面死掉就行了,速度不可能快的,不可能你写的程序比微软自带还快的

#8


如果我把这样的拷贝放到局域网里进行,是用winsock来发送好呢,还是直接拷贝快! 不过直接拷贝容易把局域网的带宽占用完了,多台工作站去拷贝一台服务器的目录,也容易把服务器拷贝得慢如蜗牛.....但是象这么复杂的目录用winsock来传送好像太烦琐了,不太现实.

看到网上有些网吧游戏更新程序,用一个服务器做目录,然后让下面的工作站去比较更新. 目录和文件进行比较倒是很容易也很快,这我也能办到. 但接下来的拷贝是怎么做的呢. 网络带宽以及服务器的磁盘承受能力, 用winsock去发送这么复杂的文件夹文件,想都不用想,何况工作站不止一台呢?

哪位能给个思路. 局域网一台服务器上的一个目录(含子目录),N台工作站里的同一目录,同时对服务器上的这个目录进行文件(夹)比较,发现服务器的目录内容有变化,就把更新的内容复制到本地的相对目录来.
目录内容更新比较很容易,更新拷贝从原理也很简单,但情况就象我1楼帖子说的那样. 现在我没有用winsock来做,主要考虑文件夹的复杂性,用winsock传输太麻烦了,而且,如果用tcp传输又没有广播功能,用UDP广播,可靠性不够.

不知道高手们要解决局域网上目录更新,1台服务器对多台工作站的方式,会采用什么思路呢?

#9


在局域网内,有共享条件,当然不要用winsock,为减小占用与重复操作,
1、你应在服务端用程序自动建一个所有相关或最新文件列表
2、客户端下载列表自己分析需更新文件,分别自建需更新文件的列表,再下载文件
3、若局域网客户机也可互相访问,你还可仿照BT的方式,由不同客户机分担不同文件夹段的更新,这只需在服务器列表中指明位置就行了,也容易实现。

#10


谢谢homezj(小吉) 

我目前就做的你说的 1 2两个步骤.
第3个步骤是个好方法,不会呀,能把第3步骤的思路给得再明确些吗?

呵呵,真有意思,我在csdn上就提过3个问题,全部是你解答的.哈哈,谢谢.

#11


我这样考虑,做个服务端,当一台工作站更新完成后,就给服务端发送一个消息,告诉服务器,它已经更新完毕了.服务器把这个工作站的一些信息记录下来. 每个客户端要更新前都先给服务器发送一个请求,服务器如果有记录就告诉这个工作站,到另外一个已经更新过的工作站去比较更新去.同时删除掉这个记录,如果服务器没有已经更新过的工作站的记录,就自己承担提过更新的任务. 

这样做,服务器减轻了一点压力,不如你说的不同工作站分段更新来得好,但是编程方面就容易多了.因为下面的工作站重启关机没有任何规律,我无法把分段的任务明确分配给哪台工作站.

#12


想想还是不行,应该学BT的方法. BT是什么方面呢?:)

#13


按某种方法排序,然后分段,分配给各工作站,各工作站自己负责的段作为服务器来给别人服务

#14


工作站如果关机,无法提供服务,工作由服务器来完成

#15


还要动用BT技术啊...这个复制可真是经典了!

#16


是呀,网络复制得考虑网络带宽的占用,以及被拷贝磁盘的压力问题. 采用分段比较拷贝,对减轻服务器压力,增加拷贝速度确实很重要.要不你试试,弄多台工作站去拷贝你服务器,你服务器会慢如蜗牛.

还有种想法,把服务器做成FTP,工作站比较文件后更新下载. 那些ftp服务器可以同时承受那么多下载任务,应该比直接拷贝承受力强些.

#17


呵呵,这么巧,都是我答的,我还没注意,有缘呀!
前面我想的也只是思路,没实际做过,不敢乱说。

FTP也好,HTTP也好,我觉得都可满足,只是速度与效率问题。

我想得没你说的那么复杂,我甚至认为可以不做专门服务器程序,不用进行通讯,只是将总列表放在服务器一个共享路径下(当然是只读的),每个下载过的机器,都在另一个可写的路径下,留下一个自己下载内容的列表,客户机先在这些列表中搜索是否有客户机可用,若没有或尝试连接不能访问,再去找总列表下的服务器位置去复制。

我不了解你们局域网的特定环境,我想肯定是交换机啦,要是HUB那就不要想分享方式了^_^。

#18


我遇到过类似问题,其实把部分小文件通过调用外部命令压缩后传输要快很多。可以做个判断,文件小于多少的全压缩到一个文件(如果太多的话压一个),楼主试试效果应该有的,我以前用过

#19


不过说实话...BT技术不会有助你这样的应用!
因为宽带是你的,机器与机器之间通道都这么宽.怎么BT也不能把这样的通道扩宽!
另外,在"BT"中还有很多很多的信息交换.不但没有助益,还会成为拖累!
如果你是因为不可以让一台机器占用过多的带宽,你可以考虑限流:实现平均分配带宽!
这样的话,建议用Sock来搞!这样就不是单单的复制这么简单了!

另外,VB+Winsock请不要过份的幻想这对组合!
然而也不是不能.但对于这么做之后,就不是拷贝文件了.而是同步数据!也就不符合这贴子的主题了.不作评论,见谅

#20


这样:
Private Sub Command1_Click()
    Shell "xcopy D:\xxx\*.* c:\yyy\*.* /s"
End Sub


如果不想让用户看到copy过程,就这样:
Private Sub Command1_Click()
    Shell "xcopy D:\xxx\*.* c:\yyy\*.* /s", vbHide
End Sub

#21


没看清问题就回复了,抱歉。
个人人为BT的思想可行。但是必须是你的局域网是交换机而不是HUB。否则BT的方式只会给你添麻烦。
BT的思想基本上就是让你的服务器尽可能的充当一个列表的功能。
就像这样:

服务器:“嘿嘿,我更新了文件,谁要?来我这里找!”
客户1:“我要文件A!”
服务器:“客户1,准备接收!其他人等一等!”
客户1:“文件A接受完毕!”

服务器:“OK!现在我空闲,谁还要文件?”
客户2:“我要文件B!”
服务器:“客户2,准备接收!其他人等一等!”
客户2:“文件B接受完毕!”

服务器:“OK!现在我空闲,谁还要文件?”
客户3:“我要文件A!”
服务器:“客户3,你要的文件在客户1那里,你去找他要!”
客户3(跑到一边去自己跟客户1商量):“客户1,我要文件A!” ……

服务器:“现在我空闲,谁还要文件?”
……
……

#22


真是受益非浅

#23


我晕~这也叫"BT"!好心啰~~!pfpf

#24


呵呵,只有用winsock来限制流量,但面对复杂的目录结构,用sock来传输处理起来太麻烦了.真有点佩服那些做网吧游戏更新软件的人了.他们怎么做的.

网吧里的网络游戏种类众多,最常用的也有几十个. 每个游戏目录小则数百兆,大则几个G.而且目录结构也挺复杂的.子目录数量很多.并且这些游戏几乎天天都需要更新才能玩. 网吧的工作站一般都安装有还原软件或硬件,重启就还原. 他们就用一台不还原的机器,安装那几十个游戏,定时去更新这些游戏.那些工作站开机后自动去跟这台游戏服务器去比较游戏的差异文件,然后把更新过的文件拷贝过来. 天,这些网吧一般有几十上百台电脑,普通的百兆交换机而已,这种更新可以在网吧正常营业的情况下进行,不影响那些正在玩游戏的人,怎么做到的?????

这类游戏更新软件,分客户端和服务端. 通过服务端来安排哪些工作站开机后更新哪些游戏. 客户端就只需要输入服务端的IP就可以了. 千万别以为是什么商业软件,不少这类软件都是业余写手写的.

#25


你所说的网吧客户机根本不需要复制几个G的文件。通常有一个类似浏览器的管理程序,只需要按游戏列表显示图标和名称;点击了改图标后,如果没有下载,就下载该游戏,否则就直接运行。在局域网用共享目录复制文件不会很慢。