Чтение файлов с устройства
После того как вы нашли файл, который вы хотите скопировать с устройства, вы можете скопировать его с устройства на компьютер в одном вызове или использовать обратный вызов для чтения байтов файла непосредственно в приложение, которое затем может обрабатывать или хранить данные по своему выбору.
Ниже показано, как скопировать файл с устройства одним вызовом.
- Получите дескриптор файла на устройстве. Дескриптор можно получить с помощью рекурсивного поиска файлов или, если вы знаете постоянный идентификатор хранилища, вызвав IWMDMDevice3::FindStorage. В любом случае требуется интерфейс IWMDMStorage объекта .
- Определите, является ли хранилище файлом или папкой. С устройства можно скопировать только файлы. Вызовите IWMDMStorage::GetAttributes , чтобы получить атрибуты хранилища, которые укажут, является ли хранилище файлом или папкой.
- Запросите IWMDMStorage для IWMDMStorageControl и вызовите IWMDMStorageControl::Read, чтобы прочитать файл с устройства и сохранить его в указанном расположении.
Если вместо этого требуется считывать блок файла за блоком с устройства, необходимо реализовать интерфейс обратного вызова IWMDMOperation . Передайте этот интерфейс в вызов IWMDMStorageControl::Read, а диспетчер устройств Windows Media отправит фрагменты файловых данных в обратный вызов. Ниже показано, как считывать блок файла устройства за блоком.
- Получите интерфейс IWMDMStorage для хранилища и определите, является ли оно файлом, как описано выше.
- Подготовьте все дескрипторы файлов или другие дескрипторы, необходимые для хранения полученных данных.
- Запрос интерфейса IWMDMStorageControl хранилища
- Вызовите IWMDMStorageControl::Read , чтобы начать операцию чтения, передав интерфейс IWMDMOperation , который вы реализовали.
- 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;
}
Связанные темы