다음을 통해 공유


디바이스에서 파일 읽기

디바이스에서 복사하려는 파일을 찾은 경우 디바이스에서 컴퓨터로 파일을 한 번의 호출로 복사하거나 콜백을 사용하여 파일 바이트를 애플리케이션에 직접 읽도록 할 수 있습니다. 그러면 데이터가 적합한 대로 처리하거나 저장할 수 있습니다.

다음 단계에서는 한 번의 호출로 디바이스에서 파일을 복사하는 기본 방법을 보여줍니다.

  1. 디바이스의 파일에 대한 핸들을 가져옵니다. 재귀 파일 검색을 사용하거나 IWMDMDevice3::FindStorage를 호출하여 스토리지의 영구 ID를 알고 있는 경우 핸들을 가져올 수 있습니다. 두 경우 모두 개체의 IWMDMStorage 인터페이스가 필요합니다.
  2. 스토리지가 파일인지 폴더인지 확인합니다. 디바이스에서 파일만 복사할 수 있습니다. IWMDMStorage::GetAttributes를 호출하여 스토리지 특성을 가져옵니다. 그러면 스토리지가 파일인지 폴더인지 알 수 있습니다.
  3. IWMDMStorageControl에 대한 IWMDMStorage를 쿼리하고 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 장치 관리자 애플리케이션 만들기