简体   繁体   English

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

[英]How can I copy a large file on Windows without CopyFile or CopyFileEx?

There is a limitation on Windows Server 2003 that prevents you from copying extremely large files, in proportion to the amount of RAM you have. Windows Server 2003存在一个限制,它会阻止您复制超大文件,与您拥有的RAM量成比例。 The limitation is in the CopyFile and CopyFileEx functions, which are used by xcopy, Explorer, Robocopy, and the .NET FileInfo class. 限制在CopyFile和CopyFileEx函数中,xcopy,Explorer,Robocopy和.NET FileInfo类使用这些函数。

Here is the error that you get: 这是你得到的错误:

Cannot copy [filename]: Insufficient system resources exist to complete the requested service. 无法复制[filename]:系统资源不足,无法完成所请求的服务。

The is a knowledge base article on the subject, but it pertains to NT4 and 2000. 这是关于该主题的知识库文章 ,但它涉及NT4和2000。

There is also a suggestion to use ESEUTIL from an Exchange installation, but I haven't had any luck getting that to work. 还有一个建议是从Exchange安装中使用ESEUTIL ,但我没有运气这么做。

Does anybody know of a quick, easy way to handle this? 有人知道一个快速,简单的方法来处理这个问题吗? I'm talking about >50Gb on a machine with 2Gb of RAM. 我在谈论带有2Gb RAM的机器上> 50Gb。 I plan to fire up Visual Studio and just write something to do it for me, but it would be nice to have something that was already out there, stable and well-tested. 我计划启动Visual Studio并为我编写一些东西,但是有一些已经存在的东西,稳定且经过充分测试会很好。

[Edit] I provided working C# code to accompany the accepted answer. [编辑]我提供了工作C#代码以配合接受的答案。

The best option is to just open the original file for reading, the destination file for writing and then loop copying it block by block. 最好的选择是打开原始文件进行读取,写入目标文件,然后逐块循环复制。 In pseudocode : 在伪代码中:

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();

[Edit by Asker] Ok, this is how it looks in C# (it's slow but it seems to work Ok, and it gives progress): [由Asker编辑]好吧,这就是它在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");
        }
    }
}

If you want to write code, one way you can optimize is sending the file in chunks (like using MTOM ). 如果要编写代码,可以优化的一种方法是以块的形式发送文件(比如使用MTOM )。 I used this approach for sending down huge files from a DataCenter down to our office for printing.. 我使用这种方法将大型文件从DataCenter发送到我们的办公室进行打印。

Also, check the TeraCopy utility mentioned here .. 另外,请检查此处提到的TeraCopy实用程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何让CopyFileEx报告回来以便我可以取消文件复制操作? - How do I get CopyFileEx to report back so I can cancel a file copy operation? 如何在不增加文件缓存的情况下将大文件复制到 Windows 中的网络共享/从网络共享复制? PowerShell 或 .NET,理想情况下 - How can I copy a large file to/from a network share in Windows without inflating the file cache? PowerShell or .NET, ideally CopyFileEx与System.IO.File.Copy() - CopyFileEx vs System.IO.File.Copy() 使用CopyFileEx复制另一个用户的加密文件 - Use CopyFileEx to copy encrypted file of another user 使用模拟和 CopyFileEx 从 Kernel DLL 复制文件? - Copy file using impersonation and CopyFileEx from Kernel DLL? 如何在不加载到内存的情况下对大型csv文件进行排序 - How can i sort large csv file without loading to memory 为什么CopyFileEx的FileUtilities.CopyFile包装器会干扰winforms? - Why is FileUtilities.CopyFile wrapper for CopyFileEx interfering with winforms? 如何将大文件(&gt; 1 GB)的编码转换为Windows 1252而不会出现内存不足异常? - How do I convert encoding of a large file (>1 GB) in size - to Windows 1252 without an out-of-memory exception? 如何在Windows Phone 8中使用没有列表框的xml文件? - How can I use xml file without listbox in windows phone 8? 何时使用PInoke? -PInvoke CopyFile与File.Copy - When to use PInoke? - PInvoke CopyFile versus File.Copy
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM