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

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

Ответы [ 5 ]

6 голосов
/ 01 июня 2011

В 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;
        }
    }
5 голосов
/ 07 сентября 2008

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

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

4 голосов
/ 07 сентября 2008

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

РЕЗЮМЕ

Есть флаг для CreateFile () называется FILE_FLAG_SEQUENTIAL_SCAN, который направит менеджер кэша в получить доступ к файлу последовательно.

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

3 голосов
/ 07 сентября 2008

Если вы не возражаете против использования инструмента, ESEUTIL отлично сработал для меня.

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

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

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

1 голос
/ 01 декабря 2012

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

...