封装几个关于流IStream的功能函数

// =====================================================
// 根据文件创建流对象
// 参数:pszFile 文件路径
//      ppStream 保存创建的流对象
// 返回值:返回创建成功与否
// 说明:用完ppStream需释放
// =====================================================
BOOL  CreateStreamFromFile (LPCTSTR pszFile, IStream** ppStream)
{
    
//打开文件
    HANDLE hFile = ::CreateFile (pszFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
    
if (hFile == INVALID_HANDLE_VALUE)
        
return FALSE;

    BOOL  bSuccess 
= TRUE;
    
do 
    {
        bSuccess 
= FALSE;

        
//获取文件长度
        LARGE_INTEGER lSize;
        
if (!::GetFileSizeEx (hFile, &lSize))
            
break;

        
//分配文件长度大小的内存块
        HGLOBAL hGlobal;
        hGlobal 
= ::GlobalAlloc (GPTR, lSize.LowPart);
        
if (hGlobal == NULL)
            
break;

        
//将文件数据读入内存块
        void* pBuffer = (void*)hGlobal;
        DWORD dwReaded(
0);
        
if (::ReadFile (hFile, pBuffer, lSize.LowPart, &dwReaded, NULL))
        {
            
//在内存块上创建流
            bSuccess = SUCCEEDED (::CreateStreamOnHGlobal (hGlobal, TRUE, ppStream));
        }

    } 
while (FALSE);
    
    ::CloseHandle (hFile);

    
return bSuccess;
}

// =====================================================
// 获取流的长度
// 参数:pStream 要获取长度的流指针
//      puiLength 保存获取到的长度
// 返回值:返回获取成功与否
// =====================================================
BOOL GetStreamLength (IStream* pStream, ULARGE_INTEGER* puiLength)
{
    _ASSERT ((pStream 
!= NULL) && (puiLength != NULL));
    BOOL  bSuccess 
= FALSE;

    
//移动偏移
    LARGE_INTEGER lMov;
    lMov.QuadPart  
= 0;

    ULARGE_INTEGER ulEnd,ulBegin;
    HRESULT hr 
= S_FALSE;

    
do
    {
        
//克隆一个指向相同字节的流,此流拥有独立的seek指针
        
//避免因为移动seek指针而影响目标流的读取
        CComPtr<IStream> spStreamClone;
        hr 
= pStream->Clone (&spStreamClone);
        
if (FAILED(hr))
            
break;

        
//移动到流结尾, ulEnd保存位置信息
        hr  =  spStreamClone->Seek (lMov, STREAM_SEEK_END, &ulEnd);
        
if (FAILED(hr))
            
break;

        
//移动到流开头, ulEnd保存位置信息
        hr  =  spStreamClone->Seek (lMov, STREAM_SEEK_SET, &ulBegin);
        
if (FAILED(hr))
            
break;
        
        
//差值即是流的长度
        puiLength->QuadPart  =  ulEnd.QuadPart - ulBegin.QuadPart;
        bSuccess   
=  TRUE;
    }
while(FALSE);

    
return bSuccess;
}

// =====================================================
// 创建一内存流
// 参数:dwSize 流的长度
//      ppStream 保存创建的流
// 返回值:返回创建成功与否
// =====================================================
BOOL CreateCompatileStream (SIZE_T dwSize, IStream** ppStream)
{
    _ASSERT (dwSize 
!= 0);
    BOOL  bSuccess  
=  FALSE;

    
//分配指定大小的内存块
    HGLOBAL hGlobal;
    hGlobal 
= ::GlobalAlloc (GPTR, dwSize);
    
if (hGlobal != NULL)
    {
        
//创建指向该内存块的流
        
//指定fDeleteOnRelease为TRUE 当释放流时会自动删除分配的内存
        bSuccess = SUCCEEDED (::CreateStreamOnHGlobal (hGlobal, TRUE, ppStream));
    }
    
return bSuccess;
}
原文地址:https://www.cnblogs.com/fangkm/p/1637097.html