2008-09-18 5 views
9

Es gibt eine Einschränkung für Windows Server 2003, die verhindert, dass Sie extrem große Dateien im Verhältnis zum verfügbaren Arbeitsspeicher kopieren können. Die Einschränkung liegt in den CopyFile- und den CopyFileEx-Funktionen, die von Xcopy, Explorer, Robocopy und der .NET FileInfo-Klasse verwandt werden. HierWie kann ich eine große Datei unter Windows ohne CopyFile oder CopyFileEx kopieren?

ist der Fehler, die Sie erhalten:

kann nicht kopiert werden [Dateiname]: Nicht genügend Systemressourcen, um den angeforderten Dienst auszuführen.

Das ist ein knowledge base article zu diesem Thema, aber es bezieht sich auf NT4 und 2000

Es gibt auch einen Vorschlag zu use ESEUTIL von einer Exchange-Installation, aber ich habe kein Glück bekommen, die zur Arbeit hatte .

Kennt jemand eine schnelle, einfache Möglichkeit, damit umzugehen? Ich spreche von> 50 GB auf einer Maschine mit 2 GB RAM. Ich plane, Visual Studio zu starten und schreibe einfach etwas, um es für mich zu machen, aber es wäre schön, etwas zu haben, das bereits da draußen ist, stabil und gut getestet.

[Bearbeiten] ich zur Verfügung gestellt C# -Code, um die angenommene Antwort zu begleiten.

Antwort

13

Die beste Option ist, nur die Originaldatei zum Lesen zu öffnen, die Zieldatei zum Schreiben und dann die Schleife zu kopieren, Block für Block. In Pseudo-Code:

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

[Bearbeiten von Asker] Ok, das ist, wie es in C# sieht (es ist langsam, aber es scheint gut zu funktionieren, und es gibt Fortschritte):

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

Verwendung mindestens einer 100KB besser, einen 1MB Puffer. Dies wird die Dateikopie enorm beschleunigen! –

+1

Sie haben 2 GB zu spielen mit ...;) Im Ernst, Aaron hat recht - den Lese-/Schreibpuffer hochfahren. – GalacticCowboy

6

Wenn Sie wollen Code schreiben, eine Möglichkeit, die Sie optimieren können, ist das Senden der Datei in Chunks (wie mit MTOM). Ich habe diesen Ansatz für das Senden von unten große Dateien von einem Datencenter in unser Büro nach unten für den Druck ..

Überprüfen Sie auch die TeraCopy Dienstprogramm here erwähnt ..

Verwandte Themen