复制文件而不使用Windows文件caching

任何人都知道将文件从pathA复制到pathB并抑制Windows文件系统caching的方法?
典型用途是将USB驱动器或服务器上的大文件复制到本地计算机。 如果文件真的很大,Windows似乎将所有东西都交换出来,例如2GiB。 喜欢在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_SEQUENTIAL_SCAN,它将指示高速缓存管理器顺序访问文件。

任何人通过顺序访问阅读可能的大文件都可以指定这个标志来提高性能。 如果您正在读取“大部分”连续的文件,则此标志非常有用,但您偶尔会跳过小范围的字节。

如果你不介意使用一个工具,ESEUTIL为我工作的很好。

你可以看看这个比较缓冲和非缓冲IO功能的博客条目,以及从哪里获得ESEUTIL。

从technet博客复制一些文本:

因此,看上面的缓冲I / O的定义,我们可以看到感知性能问题的位置 – 在文件系统缓存开销。 当我们不打算在复制完成后访问源文件时,尝试将大文件从一个位置复制到另一个位置时,首选无缓冲的I / O(或原始文件复制)。 这将避免文件系统缓存开销,并防止文件系统缓存被大文件数据有效地刷新。 许多应用程序通过调用CreateFile()来创建一个空的目标文件,然后使用ReadFile()和WriteFile()函数来传输数据。 CreateFile() – CreateFile函数创建或打开文件,文件流,目录,物理磁盘,卷,控制台缓冲区,磁带驱动器,通信资源,邮筒或命名管道。 该函数返回一个可用于访问对象的句柄。 ReadFile() – ReadFile函数从文件读取数据,并从文件指针指示的位置开始。 您可以将这个函数用于同步和异步操作。 WriteFile() – WriteFile函数将数据写入文件指针指定位置的文件。 此功能是为同步和异步操作而设计的。 要在网络上复制非常大的文件,我选择的复制实用程序是ESEUTIL,它是Exchange提供的数据库实用程序之一。

Eseutil是一个正确的答案,同样从Win7 / 2008 R2开始,你可以使用Xcopy中的/ j开关,它具有相同的效果。