Слишком медленное перемещение файловых кластеров с помощью FSCTL_MOVE_FILE

#c #c #winapi #deviceiocontrol

#c #c #winapi #deviceiocontrol

Вопрос:

Я пишу небольшую программу для перемещения виртуальных кластеров больших файлов (от 1 ГБ до 4 ГБ) внутри USB-накопителя, используя DeviceIoControl с управляющим кодом FSCTL_MOVE_FILE. Флешка отформатирована как FAT32 (это обязательное требование) с размером единицы выделения 64 КБ. Пока я могу перемещать файлы без проблем, но процесс идет очень медленно.

Я провел некоторое тестирование с нефрагментированным файлом размером 100 МБ (я убедился, что никакие другие процессы не использовали флешку при перемещении файла), и это занимает около. 2 минуты до реального перемещения. Копирование файлов внутри флешки занимает не так много времени, поэтому должно быть возможно достичь более высокой скорости, чем эта.

Вот соответствующая часть моего кода:

 HANDLE volumeHandle = CreateFile(    // Opening volume handle
    volumeDrive.c_str(),
    GENERIC_READ,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);
if (volumeHandle == INVALID_HANDLE_VALUE)
{
    ReportError(L"Invalid volume handle");
    return 1;
}

MOVE_FILE_DATA moveData = {0};
moveData.FileHandle = CreateFile(     // Opening file handle
    argv[1],
    GENERIC_READ | GENERIC_WRITE,
    0,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);
if (moveData.FileHandle == INVALID_HANDLE_VALUE)
{
    ReportError(L"Invalid file handle");
    return 1;
}

// Fill rest of input buffer
moveData.StartingVcn.QuadPart = 0;
moveData.StartingLcn.QuadPart = destination.startingLCN;
moveData.ClusterCount = (DWORD)totalFileLengthInClusters;
DWORD unused;

// Move file
BOOL result = DeviceIoControl(
    volumeHandle,                   // handle to volume
    FSCTL_MOVE_FILE,                // dwIoControlCode
    amp;moveData,                      // MOVE_FILE_DATA structure
    sizeof(moveData),               // size of input buffer
    NULL,                           // lpOutBuffer
    0,                              // nOutBufferSize
    amp;unused,                        // number of bytes returned
    NULL                            // OVERLAPPED structure
);
 

Мой вопрос: использую ли я правильные флаги при открытии дескрипторов тома и файла для оптимальной скорости? Могу ли я что-нибудь еще сделать, чтобы ускорить процесс перемещения?

Комментарии:

1. Мне нужно, чтобы некоторые файлы постоянно размещались на диске определенным образом. Я не могу использовать инструмент дефрагментации, потому что мне нужно немного больше контроля над тем, где файлы должны находиться на диске.

2. Какой уровень USB-контроллера и накопителя вы используете? Если они оба не USB 3, это будет медленно.

3. Я использую флешку USB 3, подключенную к порту USB 2. Но USB 2 должен поддерживать скорость записи не менее 10 МБ / с на полностью дефрагментированном диске, и сейчас я получаю менее 1 МБ / с, поэтому я не думаю, что это причина медлительности.