Скопируйте файл без использования файлового кэша Windows

StackOverflow https://stackoverflow.com/questions/48679

Вопрос

Кто-нибудь знает способ скопировать файл из пути A в путь B и подавить кеш файловой системы Windows?
Обычное использование — копирование большого файла с USB-накопителя или сервера на локальный компьютер.Windows, кажется, меняет все местами, если файл действительно большой, например.2ГиБ.Предпочитаю пример на C#, но я предполагаю, что это будет какой-то вызов Win32, если это возможно.

Это было полезно?

Решение

Еще важнее то, что есть FILE_FLAG_WRITE_THROUGH и FILE_FLAG_NO_BUFFERING.

В MSDN есть хорошая статья о них обоих: http://support.microsoft.com/kb/99794

Другие советы

В C# я нашел что-то вроде этого, это можно изменить, чтобы скопировать непосредственно в целевой файл:

    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;
        }
    }

Я не уверен, поможет ли это, но взгляните на Повышение производительности с помощью FILE_FLAG_SEQUENTIAL_SCAN.

КРАТКОЕ СОДЕРЖАНИЕ

Существует флаг для createfile () с именем file_flag_sectient_scan, который направит менеджера Cache к последовательному доступу к файлу.

Любой, кто читает потенциально большие файлы с последовательным доступом, может указать этот флаг для повышения производительности.Этот флаг полезен, если вы читаете файлы, которые «в основном» последовательны, но иногда вы пропускаете небольшие диапазоны байтов.

Если вы не против использовать какой-либо инструмент, ESEUTIL мне отлично подошёл.

Вы можете проверить это блог запись, сравнивающая буферизованные и небуферизованные функции ввода-вывода и откуда взять ESEUTIL.

копирование текста из блога technet:

Итак, взглянув на приведенное выше определение буферизованного ввода-вывода, мы можем увидеть, в чем заключаются предполагаемые проблемы с производительностью - в издержках кэша файловой системы.Небуферизованный ввод-вывод (или необработанное копирование файла) предпочтителен при попытке скопировать большой файл из одного места в другое, когда мы не собираемся получать доступ к исходному файлу после завершения копирования.Это позволит избежать накладных расходов на кэш файловой системы и предотвратить эффективную очистку кэша файловой системы большими файловыми данными.Многие приложения выполняют это, вызывая CreateFile() для создания пустого файла назначения, а затем используя функции ReadFile() и WriteFile() для передачи данных.CreateFile() — функция CreateFile создает или открывает файл, файловый поток, каталог, физический диск, том, консольный буфер, ленточный накопитель, коммуникационный ресурс, почтовый ящик или именованный канал.Функция возвращает дескриптор, который можно использовать для доступа к объекту.ReadFile() — функция ReadFile считывает данные из файла и начинается с позиции, указанной указателем файла.Эту функцию можно использовать как для синхронных, так и для асинхронных операций.WriteFile() — функция WriteFile записывает данные в файл в позиции, указанной указателем файла.Эта функция предназначена как для синхронной, так и для асинхронной работы.Для копирования файлов очень большого размера по сети я предпочитаю утилиту копирования ESEUTIL, которая является одной из утилит баз данных, поставляемых с Exchange.

Eseutil - правильный ответ, также, начиная с Win7/2008 R2, вы можете использовать переключатель /j в Xcopy, который имеет тот же эффект.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top