2008-09-18 5 views
9

Existe una limitación en Windows Server 2003 que le impide copiar archivos extremadamente grandes, en proporción a la cantidad de RAM que tiene. La limitación está en las funciones CopyFile y CopyFileEx, que son utilizadas por xcopy, Explorer, Robocopy y la clase .NET FileInfo.¿Cómo puedo copiar un archivo grande en Windows sin CopyFile o CopyFileEx?

Aquí está el error que se obtiene:

No se puede copiar [nombre de archivo]: Existen recursos de sistema insuficientes para completar el servicio solicitado.

El es un knowledge base article sobre el tema, sino que se refiere a NT4 y 2000.

También hay una sugerencia de use ESEUTIL de una instalación de Exchange, pero no he tenido ninguna suerte conseguir que al trabajo .

¿Alguien sabe de una manera rápida y fácil de manejar esto? Estoy hablando de> 50 Gb en una máquina con 2 Gb de RAM. Planeo arrancar Visual Studio y simplemente escribir algo para hacerlo por mí, pero sería bueno tener algo que ya estuviera disponible, estable y bien probado.

[Editar] Proporcioné el código de trabajo C# para acompañar la respuesta aceptada.

Respuesta

13

La mejor opción es simplemente abrir el archivo original para leer, el archivo de destino para escribir y luego copiarlo en bloque, bloque por bloque. En pseudocódigo:

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

[Editar autor de la pregunta] Ok, esto es lo que parece en C# (es lento pero parece funcionar bien, y da curso):

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

Uso de al menos un 100KB mejor un buffer de 1 MB. ¡Esto acelerará enormemente la copia del archivo! –

+1

Tienes 2 GB para jugar ...;) En serio, Aaron tiene razón: aumenta el búfer de lectura/escritura. – GalacticCowboy

6

Si Si desea escribir código, una forma de optimizar es enviar el archivo en fragmentos (como usar MTOM). He utilizado este enfoque para el envío de archivos de gran tamaño hacia abajo desde un centro de datos a nuestra oficina para la impresión ..

Además, verifique la utilidad TeraCopy mencionó here ..

Cuestiones relacionadas