智能文件复制算法(os独立)

时间:2010-01-14 13:22:59

标签: .net file filesystems copy

我正在尝试创建一种快速且有点智能的文件复制算法(在c#中,但与平台无关)。

我的目标:

  • 我不想使用任何平台特定代码(没有pinvokes或任何东西)
  • 我想利用多个内核,但这似乎很愚蠢,因为同时进行读/写似乎比较慢? (如果我错了,请纠正我)
  • 我想跟踪复制进度,因此File.Copy不是一个选项

我提出的代码并不特别,我正在研究如何加速它:

public bool Copy(string sourcePath, string destinationPath, ref long copiedSize, long totalSize, int fileNum, int fileCount, CopyProgressCallback progressCallback)
{
    FileStream source = File.OpenRead(sourcePath);
    FileStream dest = File.Open(destinationPath, FileMode.Create);

    int size = (int)(1024 * 256); // 256KB
    int read = 0;

    byte[] buffer = new byte[size];

    try
    {
        while ((read = source.Read(buffer, 0, size)) != 0)
        {
            dest.Write(buffer, 0, read);

            copiedSize += read;
            progressCallback(copiedSize, totalSize, fileNum, fileCount, j);
        }

        return true;
    }
    catch
    {
        // No I don't care about exception reporting.       
        return false;           
    }
    finally
    {
        source.Close();
        dest.Close();
    }
}

我尝试过但没有成功的事情:

  • 随着时间的推移增加缓冲区(速度和CD / DVD的缓存问题)
  • 尝试'CopyFileEx' - pinvokes正在放慢复制
  • 尝试了许多不同的缓冲区大小,256KB似乎是最佳解决方案
  • 在写作时试图读 - 慢下来
  • 更改'progressCallback'以在1秒后更新UI(使用秒表类) - 这显着提高了速度

任何建议都是受欢迎的 - 我会在尝试新内容时更新代码/内容。建议不要' 必须是代码 - 只是想法。

2 个答案:

答案 0 :(得分:1)

如果没有多个读/写磁头可能意味着多个磁盘,那么多个核没有多大用处。由于您的问题与平台无关,我可以建议使用并行I / O系统并让所有这些核心分享工作而不是空闲。

如果您将自己限制在具有单个读/写臂且每个表面一个头部的单个磁盘上,则需要最小化臂的移动。您可能希望从一个曲面上的轨道读取并写入另一个曲面上的相同轨道。或者你可能想要从一个表面读取一个扇区并复制到同一表面上同一轨道上的另一个扇区。

然而,所有这些都涉及非常低级别(对我而言,他们看起来非常低级别)操作。通用计算的整体趋势似乎是不断地为程序员提供简单易用的工具,代价是可以轻松访问低级操作。您自己设定的任务大致如下:

欺骗C#以我想要的方式访问磁盘,而不是按照它想要的方式访问磁盘。

祝你好运: - )

标记

PS你提到的CD / DVD表明,虽然你没有说明,但是你正试图从磁盘快速复制到CD / DVD。如果是这样,您可能会考虑首先进行磁盘复制,让复印机重新开始工作,然后将复制复制到另一个核心的CD / DVD上。

答案 1 :(得分:0)

你的速度会受到很多因素的影响,文件系统的簇大小,文件碎片,磁盘接口类型(ide / sata / etc),其他进程的其他磁盘操作,你有什么。

每台计算机和操作参数都会产生差异,从而产生不同的结果,一次代码更改可能会提高速度,但可能会降低速度。

对于小于100mb的文件,可能有一组默认设置,否则运行一组快速测试来预先配置设置。使用一定数量的缓冲区大小运行读/写速度测试,检测源和目标路径是否位于不同的磁盘上(如果是,请使复制多线程;一个读取,另一个写入)。仅使用重要的进度更新来提升/回调(进度已经改变了+ 3%)。

相关问题