如何在没有CopyFile或CopyFileEx的情况下在Windows上复制大文件?

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

这是你得到的错误:

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

这是关于这个问题的知识库文章 ,但是它涉及NT4和2000。

还有一个build议,从Exchange安装使用ESEUTIL ,但我没有任何运气得到这个工作。

有谁知道一个快速,简单的方法来处理这个? 我在2Gb内存的机器上谈论> 50Gb。 我打算启动Visual Studio,只是写一些东西来为我做,但如果有一些已经存在的东西,稳定和经过很好的testing,那将是很好的。

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

Solutions Collecting From Web of "如何在没有CopyFile或CopyFileEx的情况下在Windows上复制大文件?"

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

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

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

另外,请查看这里提到的TeraCopy工具。