复制文件而不使用Windows文件缓存
有人知道一种将文件从路径A复制到路径B并抑制Windows文件系统缓存的方法吗?
通常的用途是将大文件从USB驱动器或者服务器复制到本地计算机。如果文件很大,Windows似乎会交换所有内容,例如2GiB。
在C#中最好使用示例,但我想如果可能的话,这将是某种Win32调用。
解决方案
回答
我不确定这是否有帮助,但是请看一下使用FILE_FLAG_SEQUENTIAL_SCAN提高性能。
SUMMARY There is a flag for CreateFile() called FILE_FLAG_SEQUENTIAL_SCAN which will direct the Cache Manager to access the file sequentially. Anyone reading potentially large files with sequential access can specify this flag for increased performance. This flag is useful if you are reading files that are "mostly" sequential, but you occasionally skip over small ranges of bytes.
回答
更重要的是,还有FILE_FLAG_WRITE_THROUGH和FILE_FLAG_NO_BUFFERING。
MSDN上都有一篇不错的文章:http://support.microsoft.com/kb/99794
回答
如果我们不介意使用工具,那么ESEUTIL对我来说很棒。
我们可以检查此博客条目,以比较Buffered和NonBuffered IO函数以及从何处获取ESEUTIL。
从Technet博客复制一些文本:
因此,从上面的缓冲I / O定义来看,我们可以看到感知到的性能问题在文件系统缓存开销中所处的位置。当我们不打算在复制完成后访问源文件时,尝试将大文件从一个位置复制到另一个位置时,最好使用无缓冲的I / O(或者原始文件副本)。这将避免文件系统缓存的开销,并防止大型文件数据有效刷新文件系统缓存。许多应用程序通过调用CreateFile()创建一个空的目标文件,然后使用ReadFile()和WriteFile()函数来传输数据来实现此目的。
CreateFile()CreateFile函数创建或者打开文件,文件流,目录,物理磁盘,卷,控制台缓冲区,磁带驱动器,通信资源,邮筒或者命名管道。该函数返回可用于访问对象的句柄。
ReadFile()ReadFile函数从文件读取数据,并从文件指针指示的位置开始。我们可以将此功能用于同步和异步操作。
WriteFile()WriteFile函数在文件指针指定的位置将数据写入文件。此功能设计用于同步和异步操作。
对于在网络上复制非常大的文件,我选择的复制实用程序是ESEUTIL,它是Exchange附带的数据库实用程序之一。