c# - 如何从网络共享在 C# 中实现高性能文件复制方法?

标签 c# windows performance copy

我正在尝试实现一种文件复制方法,该方法可以与使用 Windows 资源管理器完成的复制的性能相匹配。

例如从我们的 nas 到我的电脑的副本(使用 windows 资源管理器),执行速度超过 100mb/秒。

我当前的实现以大约 55mb/秒的速度执行相同的复制,这已经比以 29mb/秒的速度执行的 System.IO.File.Copy() 更好。

static void Main(string[] args)
    {
        String src = @"";
        String dst = @"";

        Int32 buffersize = 1024 * 1024;
        FileStream input = new FileStream(src, FileMode.Open, FileAccess.Read, FileShare.None, 8, FileOptions.Asynchronous | FileOptions.SequentialScan);
        FileStream output = new FileStream(dst, FileMode.CreateNew, FileAccess.Write, FileShare.None, 8, FileOptions.Asynchronous | FileOptions.SequentialScan);

        Int32 readsize = -1;
        Byte[] readbuffer = new Byte[buffersize];
        IAsyncResult asyncread;
        Byte[] writebuffer = new Byte[buffersize];
        IAsyncResult asyncwrite;

        DateTime Start = DateTime.Now;

        output.SetLength(input.Length);

        readsize = input.Read(readbuffer, 0, readbuffer.Length);
        readbuffer = Interlocked.Exchange(ref writebuffer, readbuffer);

        while (readsize > 0)
        {
            asyncwrite = output.BeginWrite(writebuffer, 0, readsize, null, null);
            asyncread = input.BeginRead(readbuffer, 0, readbuffer.Length, null, null);

            output.EndWrite(asyncwrite);
            readsize = input.EndRead(asyncread);
            readbuffer = Interlocked.Exchange(ref writebuffer, readbuffer);
        }

        DateTime Stop = DateTime.Now;

        TimeSpan Duration = Stop - Start;
        Double speed = input.Length / Duration.TotalSeconds; // bytes/s

        System.Console.WriteLine("MY Speed : " + (speed / 1024 / 1024).ToString() + " mo/sec");

        input.Close();
        output.Close();
        System.IO.File.Delete(dst);
    }

知道如何提高性能吗?

编辑:

该文件是从基于 linux 的 nas 读取的,该 nas 具有 10 Gb 以太网接口(interface),后面有 60 个驱动器(不用担心它的性能,它工作得很好)并写入本地 raid0 可以写入数据大约 140MB/秒。

瓶颈是目标的千兆网络接口(interface),我目前的代码无法访问它。

此外,删除写入不会使读取速度更快,因此我不能超过这个 55MB/秒的读取限制。

编辑 2:

速度问题与源文件存储在网络共享上有关。 只有使用我的代码从我的本地驱动器读取才能提供 112MB/秒的速度。

编辑 3:

Samba 似乎不是问题所在。我在我的 linux nas 上用 nfs 共享替换了 cifs 共享 (samba),结果比我的 win7 客户端上的 samba 更差。

使用 nfs,我的复制方法和 Windows 资源管理器具有相同的性能,大约 42MB/秒。

我没有想法......

编辑 4:

为了确定问题出在 Windows 上,我安装了一个 debian lenny,通过 nfs 安装了我的 nas,并在单声道下使用相同的代码获得了 79MB/秒的速度。

最佳答案

尝试将缓冲区大小更改为等于硬盘上的扇区大小 - 可能是 4Kb。还可以使用 System.Diagnostics.Stopwatch 类进行计时。

我也不会费心在紧密循环中使用异步方法 - 它会产生一些开销,并从池中分配一个线程来完成工作。

同样,使用 using 语句来管理流的处理。但是请注意,这会扭曲您的时间,因为您目前正在停止计时器后处理对象。

关于c# - 如何从网络共享在 C# 中实现高性能文件复制方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3185607/

相关文章:

c# - 注册不同的实现

c# - 来电者完成连接后,我如何关闭连接?

c# - 使用 MysqlConnector 从 C# 应用程序执行 MySql 存储过程很慢?

c# - AOP Ninject 停止拦截方法被调用

windows - 找不到包 "gopkg.in/validator.v2"错误

VS : new project crashes (same files & settings) 中的 C++ 端口

algorithm - 寻找多维优化算法

c++ - 打印所有 std::locale 名称 (Windows)

java - 在 If 条件下检查 obj == null 比 obj!=null 性能更有效

.net - 引发异常的性能注意事项