Поделиться через


Чтение файлов с устройства

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

Ниже показано, как скопировать файл с устройства одним вызовом.

  1. Получите дескриптор файла на устройстве. Дескриптор можно получить с помощью рекурсивного поиска файлов или, если вы знаете постоянный идентификатор хранилища, вызвав IWMDMDevice3::FindStorage. В любом случае требуется интерфейс IWMDMStorage объекта .
  2. Определите, является ли хранилище файлом или папкой. С устройства можно скопировать только файлы. Вызовите IWMDMStorage::GetAttributes , чтобы получить атрибуты хранилища, которые укажут, является ли хранилище файлом или папкой.
  3. Запросите IWMDMStorage для IWMDMStorageControl и вызовите IWMDMStorageControl::Read, чтобы прочитать файл с устройства и сохранить его в указанном расположении.

Если вместо этого требуется считывать блок файла за блоком с устройства, необходимо реализовать интерфейс обратного вызова IWMDMOperation . Передайте этот интерфейс в вызов IWMDMStorageControl::Read, а диспетчер устройств Windows Media отправит фрагменты файловых данных в обратный вызов. Ниже показано, как считывать блок файла устройства за блоком.

  1. Получите интерфейс IWMDMStorage для хранилища и определите, является ли оно файлом, как описано выше.
  2. Подготовьте все дескрипторы файлов или другие дескрипторы, необходимые для хранения полученных данных.
  3. Запрос интерфейса IWMDMStorageControl хранилища
  4. Вызовите IWMDMStorageControl::Read , чтобы начать операцию чтения, передав интерфейс IWMDMOperation , который вы реализовали.
  5. Windows Media диспетчер устройств будет отправлять блок данных за блоком на устройство, как описано в разделе Обработка передачи файлов вручную.

Следующий пример функции C++ считывает объект хранилища с устройства. Функция принимает необязательный указатель интерфейса IWMDMOperation ; При отправке функция создаст файл явным образом и обработает запись данных в файл при реализации IWMDMOperation::TransferObjectData; Если нет, он считывает файл и сохраняет его в место назначения , указанное pwszDestName.

HANDLE m_File = NULL;

HRESULT myFileRead(IWMDMStorage pStorage, LPWSTR pwszDestName, IWMDMOperation* pOperation)
{
    HRESULT hr = S_OK;
    if ((pStorage == NULL) || (pwszDestName == NULL)) 
    {
        return E_INVALIDPARAM;
    }

    // Check that the storage is readable.
    DWORD attributes = 0;
    UINT flags = 0;
    hr = pStorage->GetAttributes(&attributes, NULL); 
    if (FAILED(hr))
    {
        return hr;
    }

    // Check that content is readable.
    if ((attributes & WMDM_FILE_ATTR_CANREAD) == 0)
    {
        return E_FAIL;
    }
    // Check that it is not abstract (such as an abstract playlist).
    else if (attributes & WMDM_STORAGE_ATTR_VIRTUAL)
    {
        return E_FAIL;
    }

    // Set some flag values for the read operation.
    flags |= WMDM_MODE_BLOCK;
    if (attributes & WMDM_FILE_ATTR_FOLDER)
    {
        flags |= WMDM_CONTENT_FOLDER;
    }
    if (attributes & WMDM_FILE_ATTR_FILE)
    {
        flags |= WMDM_CONTENT_FILE;
    }

    // Get the IWMDMStorageControl interface.
    CComQIPtr<IWMDMStorageControl> pStgControl(pStorage);
    
    // Extra steps if we want to read the file ourselves using IWMDMOperation3.
    if (pOperation != NULL)
    {
        // Create a new file and get the handle. m_File is a global variable
        // that we will use in IWMDMOperation::TransferObjectData.
        // This can also be done when IWMDMOperation::BeginRead is called.
        m_File = CreateFile(
            pwszDestName,   // Destination file name.
            GENERIC_WRITE,  // Write and append writes
            NULL,           // File can't be shared while using, and must be closed.
            NULL,           // Handle can't be inherited.
            CREATE_ALWAYS,  // Overwrite existing files.
            FILE_ATTRIBUTE_NORMAL, // No special attributes.
            NULL            // No template file supplied.
           );
        if (m_File == INVALID_HANDLE_VALUE) return E_FAIL;
        // Modify the Read() method flag. WMDM_CONTENT_FILE and WMDM_CONTENT_FOLDER 
        // are not valid flags when pOperation != NULL.
        flags |= WMDM_CONTENT_OPERATIONINTERFACE;
    }

    // Read the file.
    hr = pStgControl->Read(
             flags,        // Synchronous call specified.
             pwszDestName, // Ignored if pOperation is not NULL.
             NULL,         // No progress callback sent.
             pOperation);  // IWMDMOperation interface, if provided.
    return hr;
}

Создание приложения диспетчер устройств Windows Media