C# 如果没有CopyFile或CopyFileEx,如何在Windows上复制大文件?

C# 如果没有CopyFile或CopyFileEx,如何在Windows上复制大文件?,c#,windows,file-io,C#,Windows,File Io,Windows Server 2003上有一个限制,阻止您复制与内存量成比例的超大文件。限制在CopyFile和CopyFileEx函数中,这些函数由xcopy、Explorer、Robocopy和.NET FileInfo类使用 以下是您得到的错误: 无法复制[文件名]:系统资源不足,无法完成请求的服务 这是一个关于这个主题的问题,但它涉及到NT4和2000 还有一个建议是从Exchange安装中删除,但我还没有幸运地使它正常工作 有人知道一个快速、简单的方法来处理这个问题吗?我说的是,在一台

Windows Server 2003上有一个限制,阻止您复制与内存量成比例的超大文件。限制在CopyFile和CopyFileEx函数中,这些函数由xcopy、Explorer、Robocopy和.NET FileInfo类使用

以下是您得到的错误:

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

这是一个关于这个主题的问题,但它涉及到NT4和2000

还有一个建议是从Exchange安装中删除,但我还没有幸运地使它正常工作

有人知道一个快速、简单的方法来处理这个问题吗?我说的是,在一台内存为2Gb的机器上,内存大于50Gb。我计划启动VisualStudio并为自己编写一些东西,但如果有一些已经存在、稳定且经过良好测试的东西,那就太好了


[Edit]我提供了可工作的C#代码来附带接受的答案。

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

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]好的,这是C#中的外观(虽然速度慢,但似乎可以正常工作,并且可以取得进展):

使用系统;
使用System.Collections.Generic;
使用System.IO;
使用系统文本;
命名空间循环副本
{
班级计划
{
静态void Main(字符串[]参数)
{
如果(参数长度!=2)
{
控制台写入线(
“用法:LoopCopy.exe SourceFile DestFile”);
返回;
}
字符串srcName=args[0];
字符串destName=args[1];
FileInfo sourceFile=newfileinfo(srcName);
如果(!sourceFile.Exists)
{
Console.WriteLine(“源文件{0}不存在”,
名称);
返回;
}
long fileLen=sourceFile.Length;
FileInfo destFile=新文件信息(destName);
if(destFile.Exists)
{
Console.WriteLine(“目标文件{0}已存在”,
目的地名称);
返回;
}
int-buflen=1024;
字节[]buf=新字节[buflen];
长totalBytesRead=0;
双光子时差=0;
字符串msg=“”;
int numReads=0;
控制台。写入(“进度:”);
使用(文件流源流=
新文件流(srcName,FileMode.Open))
{
使用(FileStream destStream=
新文件流(destName,FileMode.CreateNew))
{
while(true)
{
numReads++;
int bytesRead=sourceStream.Read(buf,0,buflen);
如果(字节读==0)中断;
destStream.Write(buf,0,字节读取);
totalBytesRead+=字节读取;
如果(numReads%10==0)
{
for(int i=0;i
如果要编写代码,可以优化的一种方法是将文件分块发送(如使用)。我使用这种方法将巨大的文件从数据中心发送到我们的办公室进行打印


此外,请检查所提到的TeraCopy实用程序。

使用至少100KB的缓冲区和1MB的缓冲区。这将大大加快文件复制的速度!您有2GB可玩…;)不过,说真的,Aaron是对的——增加了读/写缓冲区。
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");
        }
    }
}