我用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比较大.哪位大虾能告诉我,怎么才能处理好我这种情况的拷贝? 主要是提速,以及不让程序假死.

解决方案 »

  1.   

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

  2.   

    这个问题涉及到操作系统底层了。要从根本上加快比较难。如果不想直接干预磁盘操作(现在的 Windows,想直接干预也难),也只能略尽人事而已:1 尽可能关闭其他程序,Copy 程序本身也要尽量少占内存空间,以便使用更大的内存缓冲区,减少磁盘往复读写的次数。
    2 经常整理磁盘,不使其存在太多碎片。从这些旮旯里把文件抠出来,再塞到另一写缝隙里去,效率可想而知。
      

  3.   

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

  4.   

    如果我把这样的拷贝放到局域网里进行,是用winsock来发送好呢,还是直接拷贝快! 不过直接拷贝容易把局域网的带宽占用完了,多台工作站去拷贝一台服务器的目录,也容易把服务器拷贝得慢如蜗牛.....但是象这么复杂的目录用winsock来传送好像太烦琐了,不太现实.看到网上有些网吧游戏更新程序,用一个服务器做目录,然后让下面的工作站去比较更新. 目录和文件进行比较倒是很容易也很快,这我也能办到. 但接下来的拷贝是怎么做的呢. 网络带宽以及服务器的磁盘承受能力, 用winsock去发送这么复杂的文件夹文件,想都不用想,何况工作站不止一台呢?哪位能给个思路. 局域网一台服务器上的一个目录(含子目录),N台工作站里的同一目录,同时对服务器上的这个目录进行文件(夹)比较,发现服务器的目录内容有变化,就把更新的内容复制到本地的相对目录来.
    目录内容更新比较很容易,更新拷贝从原理也很简单,但情况就象我1楼帖子说的那样. 现在我没有用winsock来做,主要考虑文件夹的复杂性,用winsock传输太麻烦了,而且,如果用tcp传输又没有广播功能,用UDP广播,可靠性不够.不知道高手们要解决局域网上目录更新,1台服务器对多台工作站的方式,会采用什么思路呢?
      

  5.   

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

  6.   

    谢谢homezj(小吉) 我目前就做的你说的 1 2两个步骤.
    第3个步骤是个好方法,不会呀,能把第3步骤的思路给得再明确些吗?呵呵,真有意思,我在csdn上就提过3个问题,全部是你解答的.哈哈,谢谢.
      

  7.   

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

  8.   

    是呀,网络复制得考虑网络带宽的占用,以及被拷贝磁盘的压力问题. 采用分段比较拷贝,对减轻服务器压力,增加拷贝速度确实很重要.要不你试试,弄多台工作站去拷贝你服务器,你服务器会慢如蜗牛.还有种想法,把服务器做成FTP,工作站比较文件后更新下载. 那些ftp服务器可以同时承受那么多下载任务,应该比直接拷贝承受力强些.
      

  9.   

    呵呵,这么巧,都是我答的,我还没注意,有缘呀!
    前面我想的也只是思路,没实际做过,不敢乱说。FTP也好,HTTP也好,我觉得都可满足,只是速度与效率问题。我想得没你说的那么复杂,我甚至认为可以不做专门服务器程序,不用进行通讯,只是将总列表放在服务器一个共享路径下(当然是只读的),每个下载过的机器,都在另一个可写的路径下,留下一个自己下载内容的列表,客户机先在这些列表中搜索是否有客户机可用,若没有或尝试连接不能访问,再去找总列表下的服务器位置去复制。我不了解你们局域网的特定环境,我想肯定是交换机啦,要是HUB那就不要想分享方式了^_^。
      

  10.   

    不过说实话...BT技术不会有助你这样的应用!
    因为宽带是你的,机器与机器之间通道都这么宽.怎么BT也不能把这样的通道扩宽!
    另外,在"BT"中还有很多很多的信息交换.不但没有助益,还会成为拖累!
    如果你是因为不可以让一台机器占用过多的带宽,你可以考虑限流:实现平均分配带宽!
    这样的话,建议用Sock来搞!这样就不是单单的复制这么简单了!另外,VB+Winsock请不要过份的幻想这对组合!
    然而也不是不能.但对于这么做之后,就不是拷贝文件了.而是同步数据!也就不符合这贴子的主题了.不作评论,见谅
      

  11.   

    这样:
    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
      

  12.   

    没看清问题就回复了,抱歉。
    个人人为BT的思想可行。但是必须是你的局域网是交换机而不是HUB。否则BT的方式只会给你添麻烦。
    BT的思想基本上就是让你的服务器尽可能的充当一个列表的功能。
    就像这样:服务器:“嘿嘿,我更新了文件,谁要?来我这里找!”
    客户1:“我要文件A!”
    服务器:“客户1,准备接收!其他人等一等!”
    客户1:“文件A接受完毕!”服务器:“OK!现在我空闲,谁还要文件?”
    客户2:“我要文件B!”
    服务器:“客户2,准备接收!其他人等一等!”
    客户2:“文件B接受完毕!”服务器:“OK!现在我空闲,谁还要文件?”
    客户3:“我要文件A!”
    服务器:“客户3,你要的文件在客户1那里,你去找他要!”
    客户3(跑到一边去自己跟客户1商量):“客户1,我要文件A!” ……服务器:“现在我空闲,谁还要文件?”
    ……
    ……
      

  13.   

    呵呵,只有用winsock来限制流量,但面对复杂的目录结构,用sock来传输处理起来太麻烦了.真有点佩服那些做网吧游戏更新软件的人了.他们怎么做的.网吧里的网络游戏种类众多,最常用的也有几十个. 每个游戏目录小则数百兆,大则几个G.而且目录结构也挺复杂的.子目录数量很多.并且这些游戏几乎天天都需要更新才能玩. 网吧的工作站一般都安装有还原软件或硬件,重启就还原. 他们就用一台不还原的机器,安装那几十个游戏,定时去更新这些游戏.那些工作站开机后自动去跟这台游戏服务器去比较游戏的差异文件,然后把更新过的文件拷贝过来. 天,这些网吧一般有几十上百台电脑,普通的百兆交换机而已,这种更新可以在网吧正常营业的情况下进行,不影响那些正在玩游戏的人,怎么做到的?????这类游戏更新软件,分客户端和服务端. 通过服务端来安排哪些工作站开机后更新哪些游戏. 客户端就只需要输入服务端的IP就可以了. 千万别以为是什么商业软件,不少这类软件都是业余写手写的.