Como Copiar um Arquivo Sem Usar o Cache de Arquivos do Windows
Quando se trata de gerenciamento de arquivos no Windows, você pode encontrar situações em que o cache de arquivos do sistema pode prejudicar o desempenho—especialmente ao lidar com arquivos grandes. Por exemplo, copiar um arquivo grande de um pen drive ou de um servidor para sua máquina local pode ser problemático, pois o Windows faz o cache do arquivo, o que pode levar à troca de dados e aumentar o tempo necessário para a operação ser concluída.
Neste post do blog, exploraremos como resolver esse problema copiando arquivos sem utilizar o cache do sistema de arquivos do Windows, especificamente usando C#.
Compreendendo o Cache do Sistema de Arquivos do Windows
Antes de mergulhar na solução de código, é importante entender o que é o cache do sistema de arquivos. O Windows usa um cache para acelerar as operações de arquivo, que geralmente envolve:
- Armazenar dados de arquivos na memória para um acesso mais rápido.
- Buscar descarregar dados de dispositivos mais lentos, como pen drives, para a memória do sistema mais rápida.
No entanto, com arquivos maiores (pense em 2 GiB ou mais), esse processo de cache pode levar a ineficiências, já que o sistema tenta gerenciar a memória disponível.
A Solução: Usando Chamadas da API Win32
Para contornar esse comportamento de cache, o Windows fornece flags específicas que você pode usar ao trabalhar com operações de arquivo. Essas flags são:
FILE_FLAG_WRITE_THROUGH
: Essa flag garante que as gravações no arquivo sejam escritas diretamente no dispositivo de armazenamento e não sejam armazenadas em cache na memória.FILE_FLAG_NO_BUFFERING
: Essa flag desabilita o cache do sistema para o arquivo, o que significa que todas as operações de leitura e gravação vão diretamente para o disco sem serem armazenadas em cache.
Você pode utilizar essas flags no seu código C# para realizar a cópia direta de arquivos sem usar o cache.
Implementação Passo a Passo em C#
Aqui está como implementar a solução em C#:
-
Adicione Bibliotecas Necessárias: Certifique-se de incluir os namespaces necessários para operações de arquivo e serviços de interop.
using System; using System.IO; using System.Runtime.InteropServices;
-
Declare Métodos Nativos: Você precisa declarar as funções necessárias da API Win32.
[DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr CreateFile( string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool ReadFile( IntPtr hFile, byte[] lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool WriteFile( IntPtr hFile, byte[] lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, IntPtr lpOverlapped); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool CloseHandle(IntPtr hObject);
-
Usando as Flags: Na sua função de cópia de arquivo, use as flags para criar os manipuladores de arquivos.
public void CopyFileWithoutCache(string sourceFilePath, string destFilePath) { const uint GENERIC_READ = 0x80000000; const uint GENERIC_WRITE = 0x40000000; const uint OPEN_EXISTING = 3; const uint FILE_FLAG_WRITE_THROUGH = 0x80000000; const uint FILE_FLAG_NO_BUFFERING = 0x20000000; IntPtr sourceHandle = CreateFile(sourceFilePath, GENERIC_READ, 0, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, IntPtr.Zero); IntPtr destHandle = CreateFile(destFilePath, GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, IntPtr.Zero); // Implementar lógica de leitura e gravação de arquivo aqui... CloseHandle(sourceHandle); CloseHandle(destHandle); }
Conclusão
Com os passos descritos acima, você pode copiar arquivos grandes de forma eficiente sem a interferência do cache do sistema de arquivos do Windows. Esse método é particularmente benéfico ao lidar com arquivos de alta capacidade transferidos de dispositivos lentos, como pen drives.
Para mais detalhes, verifique a documentação da Microsoft sobre FILE_FLAG_WRITE_THROUGH e FILE_FLAG_NO_BUFFERING.
Ao entender e aproveitar essas flags, você pode melhorar significativamente o desempenho das suas operações de arquivo. Bom codificação!