从设备读取文件
找到要从设备复制的文件后,可以通过一次调用将文件从设备复制到计算机,或使用回调将文件字节直接读取到应用程序,然后应用程序可以根据需要处理或存储数据。
以下步骤演示了在单个调用中从设备复制文件的基本方法:
- 获取设备上文件的句柄。 可以使用递归文件搜索或调用 IWMDMDevice3::FindStorage(如果知道存储的持久性 ID)来获取句柄。 在任一情况下,都需要对象的 IWMDMStorage 接口。
- 确定存储是文件还是文件夹。 只能从设备复制文件。 调用 IWMDMStorage::GetAttributes 以获取存储属性,这会告知存储是文件还是文件夹。
- 查询 IWMDMStorageControl的 IWMDMStorage,并调用 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;
}
相关主题