gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 12:45:21 26 4
gpt4 key购买 nike

我正在尝试实现一种文件复制方法,该方法可以与使用 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com