2008-09-18 75 views
9

Windows Server 2003有一个限制,它可以防止您复制超大型文件,与您拥有的RAM数量成比例。限制在CopyFile和CopyFileEx函数中,这些函数由xcopy,Explorer,Robocopy和.NET FileInfo类使用。如何在没有CopyFile或CopyFileEx的情况下在Windows上复制大文件?

这里是你的错误:

无法复制[文件名]:有足够的系统资源来完成所请求的服务。

的是关于这一主题的knowledge base article,但它涉及到NT4和2000年

还有从Exchange安装use ESEUTIL一个建议,但我没有任何运气得到那个工作。

有没有人知道一个快速,简单的方法来处理这个问题?我正在谈论2Gb内存的机器上> 50Gb。我打算启动Visual Studio,并且为我写一些东西来完成它,但是如果有一些已经存在的,稳定和经过充分测试的应用程序将会很好。

[编辑]我提供了工作的C#代码来陪同接受的答案。

回答

13

最好的选择是打开原来的文件进行读取,写入的目标文件,然后循环复制块逐块。在伪代码:

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"); 
     } 
    } 
} 
+3

至少使用100KB更好1MB的缓存。这将极大地加速文件复制! – 2008-11-19 15:02:55

6

如果你想写代码,你可以优化的一种方式是发送文件(如使用MTOM)。我用这种方法从数据中心向下发送大文件到我们的办公室打印..

此外,检查TeraCopy的效用提到here ..

相关问题