代码之家  ›  专栏  ›  技术社区  ›  Eric Z Beard

在没有copy file或copyfileex的情况下,如何在Windows上复制大文件?

  •  9
  • Eric Z Beard  · 技术社区  · 16 年前

    WindowsServer2003有一个限制,它会阻止您按照所拥有的RAM数量的比例复制非常大的文件。限制在copyfile和copyfileex函数中,这些函数由xcopy、explorer、robocopy和.NET fileinfo类使用。

    以下是您得到的错误:

    无法复制[文件名]:系统资源不足,无法完成请求的服务。

    是一个 knowledge base article 关于这个问题,但它属于NT4和2000。

    还有一个建议 use ESEUTIL 从一个交换装置,但我没有任何运气使它工作。

    有人知道一个快速,简单的方法来处理这个吗?我说的是一台内存为2GB的机器上的50GB。我计划启动Visual Studio,并为我编写一些东西来完成它,但是如果有一些已经存在的东西,稳定并且经过了很好的测试,那就太好了。

    [编辑] 我提供了有效的C代码,以配合接受的答案。

    2 回复  |  直到 16 年前
        1
  •  13
  •   Eric Z Beard    16 年前

    最好的选择是只打开要读取的原始文件、要写入的目标文件,然后逐块循环复制它。在伪代码中:

    f1 = open(filename1);
    f2 = open(filename2, "w");
    while( !f1.eof() ) {
      buffer = f1.read(buffersize);
      err = f2.write(buffer, buffersize);
      if err != NO_ERROR_CODE
        break;
    }
    f1.close(); f2.close();
    

    [阿斯克编辑] 好的,这就是它在c中的样子(它很慢,但似乎工作正常,而且它能进步):

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    
    namespace LoopCopy
    {
        class Program
        {
            static void Main(string[] args)
            {
                if (args.Length != 2)
                {
                    Console.WriteLine(
                      "Usage: LoopCopy.exe SourceFile DestFile");
                    return;
                }
    
                string srcName = args[0];
                string destName = args[1];
    
                FileInfo sourceFile = new FileInfo(srcName);
                if (!sourceFile.Exists)
                {
                    Console.WriteLine("Source file {0} does not exist", 
                        srcName);
                    return;
                }
                long fileLen = sourceFile.Length;
    
                FileInfo destFile = new FileInfo(destName);
                if (destFile.Exists)
                {
                    Console.WriteLine("Destination file {0} already exists", 
                        destName);
                    return;
                }
    
                int buflen = 1024;
                byte[] buf = new byte[buflen];
                long totalBytesRead = 0;
                double pctDone = 0;
                string msg = "";
                int numReads = 0;
                Console.Write("Progress: ");
                using (FileStream sourceStream = 
                  new FileStream(srcName, FileMode.Open))
                {
                    using (FileStream destStream = 
                        new FileStream(destName, FileMode.CreateNew))
                    {
                        while (true)
                        {
                            numReads++;
                            int bytesRead = sourceStream.Read(buf, 0, buflen);
                            if (bytesRead == 0) break; 
                            destStream.Write(buf, 0, bytesRead);
    
                            totalBytesRead += bytesRead;
                            if (numReads % 10 == 0)
                            {
                                for (int i = 0; i < msg.Length; i++)
                                {
                                    Console.Write("\b \b");
                                }
                                pctDone = (double)
                                    ((double)totalBytesRead / (double)fileLen);
                                msg = string.Format("{0}%", 
                                         (int)(pctDone * 100));
                                Console.Write(msg);
                            }
    
                            if (bytesRead < buflen) break;
    
                        }
                    }
                }
    
                for (int i = 0; i < msg.Length; i++)
                {
                    Console.Write("\b \b");
                }
                Console.WriteLine("100%");
                Console.WriteLine("Done");
            }
        }
    }
    
        2
  •  6
  •   Gulzar Nazim    16 年前

    如果您想编写代码,您可以优化的一种方法是将文件分块发送(如使用 MTOM )。我用这种方法从数据中心发送大量文件到我们的办公室进行打印。

    另外,检查提到的teracopy实用程序 here