Lendo arquivos do dispositivo
Quando encontrar um arquivo que gostaria de copiar do dispositivo, você poderá copiar o arquivo do dispositivo para o computador em uma única chamada ou usar um retorno de chamada para que os bytes de arquivo sejam lidos diretamente no aplicativo, o que pode processar ou armazenar os dados conforme eles se ajustam.
As etapas a seguir mostram a maneira básica de copiar um arquivo de um dispositivo em uma única chamada:
- Obtenha um identificador para o arquivo no dispositivo. Você pode obter o identificador usando uma pesquisa de arquivo recursiva ou, se souber a ID persistente do armazenamento, chamando IWMDMDevice3::FindStorage. Em ambos os casos, você precisa da interface IWMDMStorage do objeto .
- Determine se o armazenamento é um arquivo ou uma pasta. Somente arquivos podem ser copiados do dispositivo. Chame IWMDMStorage::GetAttributes para obter atributos de armazenamento, o que informará se o armazenamento é um arquivo ou uma pasta.
- Consulte IWMDMStorage para IWMDMStorageControl e chame IWMDMStorageControl::Read para ler o arquivo do dispositivo e salvá-lo em um local especificado.
Se, em vez disso, você quiser ler o bloco de arquivos por bloco do dispositivo, deverá implementar a interface de retorno de chamada IWMDMOperation . Passe essa interface para a chamada IWMDMStorageControl::Read e o Windows Media Gerenciador de Dispositivos enviará partes de dados de arquivo sequencialmente para o retorno de chamada. As etapas a seguir mostram como ler um bloco de arquivos de dispositivo por bloco:
- Obtenha a interface IWMDMStorage para o armazenamento e determine se ele é um arquivo, conforme descrito anteriormente.
- Prepare os identificadores de arquivo ou outros identificadores necessários para armazenar os dados recebidos.
- Consulta para a interface IWMDMStorageControl do armazenamento
- Chame IWMDMStorageControl::Read para iniciar a operação de leitura, passando a interface IWMDMOperation que você implementou.
- O Windows Media Gerenciador de Dispositivos enviará o bloco de dados por bloco para seu dispositivo, conforme descrito em Manipulando transferências de arquivos manualmente.
A função de exemplo C++ a seguir lê um objeto de armazenamento de um dispositivo. A função aceita um ponteiro de interface IWMDMOperation opcional; se enviada, a função criará um arquivo explicitamente e manipulará a gravação dos dados no arquivo em sua implementação de IWMDMOperation::TransferObjectData; caso contrário, ele lerá o arquivo e salvará no destino especificado por 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;
}
Tópicos relacionados