Our .NET app copies large files, and needs to give the user feedback; so rather than use File.Copy
we read a chunk of one file and write it to the other, and display the progress after each chunk. Nothing out of the ordinary. But what's the right size of chunk to use, to give the fastest file copy, assuming the time to display the progress is negligible?
我们的.NET应用程序复制大文件,需要向用户提供反馈;因此,我们不是使用File.Copy,而是读取一个文件的块并将其写入另一个文件,并在每个块之后显示进度。没有什么不寻常的。但是,假设显示进度的时间可以忽略不计,那么使用什么大小的块来提供最快的文件副本?
3 个解决方案
#1
You should consider using win32 function CopyFileTransacted (Vista Only) or CopyFileEx (Windows 2000 and higher). These are provided by Windows and are optimized for speed.
您应该考虑使用CopyFileTransacted Win32函数(仅限Vista)或CopyFileEx(Windows 2000及更高版本)。这些由Windows提供,并针对速度进行了优化。
I would recommend you to test your custom C# implementation performance and compare it to native File.Copy performance. If the performance is comparable (i.e. same order of magnitude) than go with your custom C# implementation. Otherwise it's better to use CopyFileTransacted or CopyFileEx function.
我建议您测试自定义C#实现性能,并将其与本机File.Copy性能进行比较。如果性能与您的自定义C#实现相当(即相同数量级)。否则最好使用CopyFileTransacted或CopyFileEx函数。
P.s. from here:
附:从这里:
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
internal static extern bool CopyFileTransacted([In] string lpExistingFileName, [In] string lpNewFileName, [In] IntPtr lpProgressRoutine, [In] IntPtr lpData, [In, MarshalAs(UnmanagedType.Bool)] ref bool pbCancel, [In] CopyFileFlags dwCopyFlags, [In] KtmTransactionHandle hTransaction);
#2
A very large buffer will give you the best transfer speed but a coarse feedback. So it's a trade-off and it also depends very much on the hardware.
一个非常大的缓冲区将为您提供最佳的传输速度,但粗略的反馈。所以这是一个权衡,它也很大程度上取决于硬件。
I did something like this a while back and settled on a 64k buffer, but you might want to experiment a little.
我不久前做了类似的事情,并在64k缓冲区上安顿下来,但你可能想尝试一下。
And whatever you pick, make sure it's a multiple of 512 (1 sector)
无论你选择什么,确保它是512的倍数(1扇区)
#3
Even when using larger chunks you can easily estimate the progress to give the user "faked" feedback. Depending on the application why don't you let the user set the size? Give the user option if he wants it :)
即使使用较大的块,您也可以轻松估计进度,为用户提供“伪造”的反馈。根据应用程序,为什么不让用户设置大小?如果他想要它,给用户选项:)
#1
You should consider using win32 function CopyFileTransacted (Vista Only) or CopyFileEx (Windows 2000 and higher). These are provided by Windows and are optimized for speed.
您应该考虑使用CopyFileTransacted Win32函数(仅限Vista)或CopyFileEx(Windows 2000及更高版本)。这些由Windows提供,并针对速度进行了优化。
I would recommend you to test your custom C# implementation performance and compare it to native File.Copy performance. If the performance is comparable (i.e. same order of magnitude) than go with your custom C# implementation. Otherwise it's better to use CopyFileTransacted or CopyFileEx function.
我建议您测试自定义C#实现性能,并将其与本机File.Copy性能进行比较。如果性能与您的自定义C#实现相当(即相同数量级)。否则最好使用CopyFileTransacted或CopyFileEx函数。
P.s. from here:
附:从这里:
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
internal static extern bool CopyFileTransacted([In] string lpExistingFileName, [In] string lpNewFileName, [In] IntPtr lpProgressRoutine, [In] IntPtr lpData, [In, MarshalAs(UnmanagedType.Bool)] ref bool pbCancel, [In] CopyFileFlags dwCopyFlags, [In] KtmTransactionHandle hTransaction);
#2
A very large buffer will give you the best transfer speed but a coarse feedback. So it's a trade-off and it also depends very much on the hardware.
一个非常大的缓冲区将为您提供最佳的传输速度,但粗略的反馈。所以这是一个权衡,它也很大程度上取决于硬件。
I did something like this a while back and settled on a 64k buffer, but you might want to experiment a little.
我不久前做了类似的事情,并在64k缓冲区上安顿下来,但你可能想尝试一下。
And whatever you pick, make sure it's a multiple of 512 (1 sector)
无论你选择什么,确保它是512的倍数(1扇区)
#3
Even when using larger chunks you can easily estimate the progress to give the user "faked" feedback. Depending on the application why don't you let the user set the size? Give the user option if he wants it :)
即使使用较大的块,您也可以轻松估计进度,为用户提供“伪造”的反馈。根据应用程序,为什么不让用户设置大小?如果他想要它,给用户选项:)