封装几个关于流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;
}

 

 

你可能感兴趣的:(Stream)