C# 不使用windows文件缓存复制文件

C# 不使用windows文件缓存复制文件,c#,windows,winapi,filesystems,file-copying,C#,Windows,Winapi,Filesystems,File Copying,有人知道将文件从路径a复制到路径B并抑制Windows文件系统缓存的方法吗? 典型的用途是将一个大文件从USB驱动器或服务器复制到本地计算机。如果文件真的很大,例如2GB,Windows似乎会将所有内容都交换掉。 我更喜欢C#中的示例,但我猜如果可能的话,这将是某种Win32调用。我不确定这是否有帮助,但请看一看 总结 CreateFile()有一个标志 调用文件\u标志\u顺序\u扫描 将指示缓存管理器 按顺序访问文件 有人在读可能很大的文件吗 使用顺序访问可以指定 此标志用于提高性能。 如果

有人知道将文件从路径a复制到路径B并抑制Windows文件系统缓存的方法吗?
典型的用途是将一个大文件从USB驱动器或服务器复制到本地计算机。如果文件真的很大,例如2GB,Windows似乎会将所有内容都交换掉。
我更喜欢C#中的示例,但我猜如果可能的话,这将是某种Win32调用。

我不确定这是否有帮助,但请看一看

总结

CreateFile()有一个标志 调用文件\u标志\u顺序\u扫描 将指示缓存管理器 按顺序访问文件

有人在读可能很大的文件吗 使用顺序访问可以指定 此标志用于提高性能。 如果您正在阅读,此标志非常有用 “大部分”连续的文件, 但是你偶尔会跳过一些小的 字节的范围


更重要的是,还有文件标志写入和文件标志无缓冲


MSDN在这两个方面都有一篇很好的文章:

如果您不介意使用工具,ESEUTIL对我来说非常有用

您可以查看此条目,比较缓冲和非缓冲IO函数以及从何处获取ESEUTIL

正在从technet博客复制一些文本:

因此,看看上面缓冲I/O的定义,我们可以看到感知到的性能问题在哪里——在文件系统缓存开销中。当我们不打算在复制完成后访问源文件时,尝试将大文件从一个位置复制到另一个位置时,最好使用无缓冲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以来,您可以在Xcopy中使用/j开关,这具有相同的效果。

我知道这个问题是11年前的事了,现在有了一种替代Xcopy的robocopy

您需要选中/J选项
/J::使用无缓冲I/O复制(建议用于大文件)

此答案虽然正确,但不是对原始问题的回答。有编辑权的人能重写吗?你能告诉我你在哪里看到Q和A之间的差异吗?我很乐意改写答案。@gabr:你的回答引用了(“更重要的”)另一个答案。不要。让你的答案独立。认为只有你回答,没有其他人。我使用这个标志也是出于同样的目的,我可以证明文件\u标志\u顺序\u扫描正在进行。如果你真的想了解缓存与文件复制的交互机制,