2008-09-07 10 views
6

¿Alguien sabe de una forma de copiar un archivo de la ruta A a la ruta B y suprimir la caché del sistema de archivos de Windows?
El uso típico es copiar un archivo grande de una unidad USB o servidor a su máquina local. Windows parece intercambiar todo si el archivo es realmente grande, p. 2GiB. Prefiero el ejemplo en C#, pero supongo que sería una llamada de Win32 de algún tipo si es posible.Copie un archivo sin usar el caché de archivos de Windows

+1

Si realmente quiere comprender la mecánica de las interacciones de la memoria caché con la copia de archivos, [esta es una lectura obligada.] (Http://blogs.technet.com/markrussinovich/archive/2008/02/04/2826167.aspx) –

Respuesta

5

Aún más importante, hay FILE_FLAG_WRITE_THROUGH y FILE_FLAG_NO_BUFFERING.

MSDN tiene un buen artículo sobre ellos tanto: http://support.microsoft.com/kb/99794

+0

Esta respuesta, aunque correcta, no es una respuesta a la pregunta original. ¿Alguien con derechos de edición puede modificarlo? –

+0

¿Puede decirme dónde ve la discrepancia entre la Q y la A? Estaré encantado de reformular la respuesta. – gabr

+1

@gabr: su respuesta hace referencia ("Aún más importante") otra respuesta. No lo hagas Haga su respuesta independiente. Piensa que solo tú respondiste, nadie más. – tzot

4

No estoy seguro si esto ayuda, pero eche un vistazo a Increased Performance Using FILE_FLAG_SEQUENTIAL_SCAN.

RESUMEN

Hay una bandera para CreateFile() llama FILE_FLAG_SEQUENTIAL_SCAN cuales dirigirá el Administrador de caché para acceder al archivo de forma secuencial.

Cualquiera que lea los archivos potencialmente grandes con acceso secuencial puede especificar esta bandera para un mayor rendimiento. Este indicador es útil si está leyendo archivos que son "en su mayoría" secuenciales, pero ocasionalmente omite pequeños rangos de bytes .

+0

Uso este indicador para los mismos fines, y puedo testificar que FILE_FLAG_SEQUENTIAL_SCAN está haciendo el trabajo. – tzot

3

Si no te importa el uso de una herramienta, ESEUTIL funcionó muy bien para mí.

Puede consultar esta entrada de blog comparando las funciones de E/S búfer y sin buffers y de dónde obtener ESEUTIL.

copiar un texto desde el blog de TechNet:

Así que buscando en la definición de búfer de E/S anterior, podemos ver dónde están los problemas de rendimiento percibido se encuentran - en la sobrecarga de la memoria caché del sistema de archivos. Se prefiere la E/S sin búfer (o una copia sin formato) cuando se intenta copiar un archivo grande de una ubicación a otra cuando no tenemos la intención de acceder al archivo fuente una vez que se completa la copia. Esto evitará la sobrecarga de la memoria caché del sistema de archivos y evitará que la memoria caché del sistema de archivos se vacíe de forma efectiva por los datos de archivos de gran tamaño. Muchas aplicaciones logran esto llamando a CreateFile() para crear un archivo de destino vacío, luego usando las funciones ReadFile() y WriteFile() para transferir los datos. CreateFile() - La función CreateFile crea o abre un archivo, secuencia de archivos, directorio, disco físico, volumen, búfer de consola, unidad de cinta, recurso de comunicaciones, ranura de correo o canalización con nombre. La función devuelve un identificador que se puede usar para acceder a un objeto. ReadFile() - La función ReadFile lee datos de un archivo y comienza en la posición que indica el puntero del archivo. Puede usar esta función para operaciones síncronas y asíncronas. WriteFile(): la función WriteFile escribe datos en un archivo en la posición especificada por el puntero del archivo. Esta función está diseñada para operación síncrona y asíncrona. Para copiar archivos de la red que son muy grandes, mi utilidad de copia preferida es ESEUTIL, que es una de las utilidades de base de datos proporcionadas con Exchange.

6

En C# He encontrado algo como esto para trabajar, esto se puede cambiar a copiar directamente al archivo de destino:

public static byte[] ReadAllBytesUnbuffered(string filePath) 
    { 
     const FileOptions FileFlagNoBuffering = (FileOptions)0x20000000; 
     var fileInfo = new FileInfo(filePath); 
     long fileLength = fileInfo.Length; 
     int bufferSize = (int)Math.Min(fileLength, int.MaxValue/2); 
     bufferSize += ((bufferSize + 1023) & ~1023) - bufferSize; 
     using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None, 
              bufferSize, FileFlagNoBuffering | FileOptions.SequentialScan)) 
     { 
      long length = stream.Length; 
      if (length > 0x7fffffffL) 
      { 
       throw new IOException("File too long over 2GB"); 
      } 
      int offset = 0; 
      int count = (int)length; 
      var buffer = new byte[count]; 
      while (count > 0) 
      { 
       int bytesRead = stream.Read(buffer, offset, count); 
       if (bytesRead == 0) 
       { 
        throw new EndOfStreamException("Read beyond end of file EOF"); 
       } 
       offset += bytesRead; 
       count -= bytesRead; 
      } 
      return buffer; 
     } 
    } 
1

Eseutil es una respuesta correcta, también desde Win7/2008 R2, puede usar el modificador/j en Xcopy, que tiene el mismo efecto.

Cuestiones relacionadas