Кто-нибудь знает способ копирования файла из пути A в путь B и подавления кеша файловой системы Windows?
Типичное использование - копирование большого файла с USB-накопителя или сервера на локальный компьютер. Кажется, что Windows заменяет все, если файл действительно большой, например. 2GiB. Предпочитаете пример на C#, но я предполагаю, что это будет вызов Win32, если это возможно.Скопировать файл без использования кеша окон
ответ
Еще важнее то, что существуют FILE_FLAG_WRITE_THROUGH и FILE_FLAG_NO_BUFFERING.
MSDN есть хорошая статья на них обоих: http://support.microsoft.com/kb/99794
Этот ответ, хотя правильный, не является ответом на исходный вопрос. Может ли кто-то с правами редактирования переписать его? – 2008-09-08 00:23:00
Я не уверен, если это поможет, но взгляните на Increased Performance Using FILE_FLAG_SEQUENTIAL_SCAN.
РЕЗЮМЕ
Существует флаг для CreateFile() называется FILE_FLAG_SEQUENTIAL_SCAN, который направит диспетчера кэша для доступа файл последовательно.
Любой, кто читает потенциально большие файлы с последовательным доступом, может указывать этот флаг для повышения производительности. Этот флаг полезен, если вы читаете файлов, которые являются «в основном» последовательными, , но вы иногда пропускаете небольшие диапазоны байтов.
Я использую этот флаг для тех же целей, и я могу засвидетельствовать, что FILE_FLAG_SEQUENTIAL_SCAN выполняет эту работу. – tzot 2008-10-11 23:24:11
Если вы не возражаете, используя инструмент, ESEUTIL работал большой для меня.
Вы можете проверить эту запись blog, сравнивая функции буферизованного и небуферизованного ввода-вывода и откуда получить ESEUTIL.
копируя текст из блога Technet:
Так, глядя на определение буферном I/O выше, мы можем увидеть, где предполагаемые проблемы производительности лежат - в накладных кэш файловой системы. Небуферизованный ввод-вывод (или необработанная копия файла) предпочтительнее при попытке скопировать большой файл из одного места в другое, когда мы не намерены обращаться к исходному файлу после завершения копирования. Это позволит избежать накладных расходов на кеш файловой системы и не позволяет эффективно кэшировать кеш файловой системы большими файловыми данными. Многие приложения выполняют это, вызывая CreateFile() для создания пустого файла назначения, а затем используя функции ReadFile() и WriteFile() для передачи данных. CreateFile() - Функция CreateFile создает или открывает файл, файловый поток, каталог, физический диск, том, буфер консоли, стример, ресурс связи, почтовый ящик или именованный канал. Функция возвращает дескриптор, который можно использовать для доступа к объекту. ReadFile() - Функция ReadFile считывает данные из файла и начинается с позиции, указанной указателем файла. Вы можете использовать эту функцию для синхронных и асинхронных операций. WriteFile() - Функция WriteFile записывает данные в файл в позиции, указанной указателем файла. Эта функция предназначена для синхронной и асинхронной работы. Для копирования файлов по сети, которые являются очень большими, моя полезная утилита копирования - это ESEUTIL, которая является одной из утилит базы данных, поставляемой с Exchange.
В 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;
}
}
Eseutil является правильным ответом, также так Win7/2008 R2, вы можете использовать переключатель/j в Xcopy, который имеет тот же эффект.
Если вы действительно хотите понять механику взаимодействия кеша с копированием файлов, [это обязательное чтение.] (Http://blogs.technet.com/markrussinovich/archive/2008/02/04/2826167.aspx) – 2008-09-07 20:21:06