Интеллектуальный алгоритм копирования файлов (независимый от ОС) - PullRequest
3 голосов
/ 14 января 2010

Я пытаюсь создать быстрый и несколько интеллектуальный алгоритм копирования файлов (в c #, но не зависит от платформы).

Мои цели:

  • Я не хочу использовать какой-либо платформо-зависимый код (никаких пинвоков или чего-либо еще)
  • Я бы хотел использовать преимущества нескольких ядер, но это кажется глупым, поскольку одновременное чтение / запись может показаться медленнее, верно? (поправьте меня, пожалуйста, если я ошибаюсь)
  • Я хочу отслеживать процесс копирования, поэтому 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' - пинвоки замедляли копирование
  • Перепробовал много разных размеров буфера, и 256 КБ кажется лучшим решением
  • Пытался читать как я пишу - помедленнее
  • Изменен 'progressCallback' для обновления пользовательского интерфейса через 1 секунду (с использованием класса секундомера) - это значительно улучшило скорость

ЛЮБЫЕ предложения приветствуются - я буду обновлять код / ​​материал, когда буду пробовать новый материал. Предложения не делайте должен быть код - только идеи.

Ответы [ 2 ]

1 голос
/ 14 января 2010

Многоядерные процессоры мало используются без нескольких головок чтения / записи, что, вероятно, означает наличие нескольких дисков. Поскольку ваш вопрос не зависит от платформы, я не стесняюсь предложить использовать систему параллельного ввода-вывода и заставить все эти ядра выполнять свою часть работы вместо простоя.

Если вы ограничиваете себя одним диском с одним рычагом для чтения / записи и одной головкой на поверхность, вам нужно минимизировать движения руки. Вы, вероятно, хотите читать с дорожки на одной поверхности и писать на ту же дорожку на другой поверхности. Или вы можете прочитать сектор с одной поверхности и скопировать его в другой сектор на той же дорожке на той же поверхности.

Однако все это включает в себя операции очень низкого уровня (на мой взгляд, они выглядят очень низкоуровневыми). Кажется, что общая тенденция в вычислениях общего назначения постоянно заключается в том, чтобы предоставить программисту простые в использовании инструменты, за счет устранения легкого доступа к операциям низкого уровня. Задача, которую вы поставили перед собой, примерно такая:

Уловка C # для доступа к диску так, как я хочу, а не так, как он хочет.

Удачи с этим: -)

Mark

PS Ваше упоминание о CD / DVD предполагает, что вы, хотя и не утверждаете, что вы пытаетесь сделать быструю копию с диска на CD / DVD. Если это так, вы можете подумать о том, чтобы сначала сделать копию на диск, вернуть копировальный аппарат в рабочее состояние и переместить копирование с копии на CD / DVD на другое ядро.

0 голосов
/ 15 января 2010

На вашу скорость могут влиять многие вещи, размер кластера файловой системы, фрагментация файла, тип интерфейса диска (ide / sata / etc), другие операции с дисками из других процессов, что у вас есть.

Каждый компьютер и параметры работы будут иметь различия, дающие разные результаты, одно изменение кода может увеличить скорость, но может уменьшить скорость.

Может иметь набор настроек по умолчанию для файлов размером менее 100 МБ, в противном случае запустите быстрый набор тестов для предварительной настройки параметров. Запустите тест скорости чтения / записи с заданным количеством размеров буфера, определите, расположены ли исходные и целевые пути на отдельных дисках (если это так, сделайте копию многопоточной: одну для чтения, другую для записи). Только повышение / обратный вызов с существенными обновлениями прогресса (прогресс, который изменился как на +3%).

...