无语的CAtlTemporaryFile类

经常需要将一些内容写进临时文件,这就需要结合GetTempPath和GetTempFileName在Windows临时目录下生成一个临时文件。ATL提供了类CAtlTemporaryFile来进行这层封装,可使用此类时,才发现该类有多么地鸡肋啊.我写了一个Demo:
        CAtlTemporaryFile fileTmp;     
        fileTmp.Create();
        fileTmp.Write( COLE2CT( bstrHtml ), wcslen( bstrHtml )  );
        fileTmp.Close( );
       
       fileTmp.TempFileName();

照理说这样应该就可以了,但一直得不到我要的文件,跟踪CAtlTemporaryFile源码才发现在成员方法Close已经把生成的文件删除了.我纳闷了,这是啥意思嘛!还让不让人用啊。再一细看,发现Close方法提供了一个参数:szNewName,Close方法将生成的文件移动到szNewName指定的文件,若不指定,则直接删除生成的文件.由于Close方法移动前会删除szNewName指定的文件已确保其不存在,因此,我最后一个希望:将szNewName指定为CAtlTemporaryFile生成的文件(由TempFileName获取)也破灭了.真是悲剧了.让我重新指定一个目标文件地址,我还用CAtlTemporaryFile干嘛啊,真的简直是鸡肋.没办法,我只有定制CAtlTemporaryFile的源码了,还好该源码没有那么多的依赖关系,十分利于拷贝,哈哈.下面是我的修改版本:

#include  < atlfile.h >

template
<   bool  bDeleted  >
class  CAtlTemporaryFileExT
{
public :
    CAtlTemporaryFileExT() 
throw ()
    {
    }

    
~ CAtlTemporaryFileExT()  throw ()
    {
        
//  Ensure that the temporary file is closed and deleted,
        
//  if necessary.
         if  (m_file.m_h  !=  NULL)
        {
            Close();
        }

        
// 如果设为自动删除,结束时则删除文件
         if ( bDeleted )
        {
            Delete();
        }
    }

    HRESULT Create(__in_opt LPCTSTR pszDir 
=  NULL, __in DWORD dwDesiredAccess  =  GENERIC_WRITE)  throw ()
    {
        TCHAR szPath[_MAX_PATH]; 
        TCHAR tmpFileName[_MAX_PATH]; 

        ATLASSUME(m_file.m_h 
==  NULL);

        
if  (pszDir  ==  NULL)
        {
            DWORD dwRet 
=  GetTempPath(_MAX_DIR, szPath);
            
if  (dwRet  ==   0 )
            {
                
//  Couldn't find temporary path;
                 return  AtlHresultFromLastError();
            }
            
else   if  (dwRet  >  _MAX_DIR)
            {
                
return  DISP_E_BUFFERTOOSMALL;
            }
        }
        
else
        {
            
if (Checked::tcsncpy_s(szPath, _countof(szPath), pszDir, _TRUNCATE) == STRUNCATE)
            {
                
return  DISP_E_BUFFERTOOSMALL;
            }
        }

        
if  ( ! GetTempFileName(szPath, _T( " TFR " ),  0 , tmpFileName))
        {
            
//  Couldn't create temporary filename;
             return  AtlHresultFromLastError();
        }
        tmpFileName[_countof(tmpFileName)
- 1 ] = ' \0 ' ;

        Checked::tcsncpy_s(m_szTempFileName, _countof(m_szTempFileName), tmpFileName, _TRUNCATE);
        SECURITY_ATTRIBUTES secatt;
        secatt.nLength 
=   sizeof (secatt);
        secatt.lpSecurityDescriptor 
=  NULL;
        secatt.bInheritHandle 
=  TRUE;

        m_dwAccess 
=  dwDesiredAccess;

        
return  m_file.Create(
            m_szTempFileName,
            m_dwAccess,
            
0 ,
            CREATE_ALWAYS,
            FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 
|  FILE_ATTRIBUTE_TEMPORARY,
            
& secatt);
    }

    HRESULT Close() 
throw ()
    {
        ATLASSUME(m_file.m_h 
!=  NULL);

        m_file.Close();

        
return  S_OK;
    }

    
    HRESULT Delete()
    {
 
         return  ::DeleteFile( m_szTempFileName )  ?  S_OK : S_FALSE;
    }
    
    HRESULT HandsOff() 
throw ()
    {
        m_file.Flush();
        m_file.Close();

        
return  S_OK;
    }

    HRESULT HandsOn() 
throw ()
    {
        HRESULT hr 
=  m_file.Create(
            m_szTempFileName,
            m_dwAccess,
            
0 ,
            OPEN_EXISTING);
        
if  (FAILED(hr))
            
return  hr;

        
return  m_file.Seek( 0 , FILE_END);
    }

    HRESULT Read(
        __out_bcount(nBufSize) LPVOID pBuffer,
        __in DWORD nBufSize,
        __out DWORD
&  nBytesRead)  throw ()
    {
        
return  m_file.Read(pBuffer, nBufSize, nBytesRead);
    }

    HRESULT Write(
        __in_bcount(nBufSize) LPCVOID pBuffer,
        __in DWORD nBufSize,
        __out_opt DWORD
*  pnBytesWritten  =  NULL)  throw ()
    {
        
return  m_file.Write(pBuffer, nBufSize, pnBytesWritten);
    }

    HRESULT Seek(__in LONGLONG nOffset, __in DWORD dwFrom 
=  FILE_CURRENT)  throw ()
    {
        
return  m_file.Seek(nOffset, dwFrom);
    }

    HRESULT GetPosition(__out ULONGLONG
&  nPos)  const   throw ()
    {
        
return  m_file.GetPosition(nPos);
    }

    HRESULT Flush() 
throw ()
    {
        
return  m_file.Flush();
    }

    HRESULT LockRange(__in ULONGLONG nPos, __in ULONGLONG nCount) 
throw ()
    {
        
return  m_file.LockRange(nPos, nCount);
    }

    HRESULT UnlockRange(__in ULONGLONG nPos, __in ULONGLONG nCount) 
throw ()
    {
        
return  m_file.UnlockRange(nPos, nCount);
    }

    HRESULT SetSize(__in ULONGLONG nNewLen) 
throw ()
    {
        
return  m_file.SetSize(nNewLen);
    }

    HRESULT GetSize(__out ULONGLONG
&  nLen)  const   throw ()
    {
        
return  m_file.GetSize(nLen);
    }

    
operator  HANDLE()  throw ()
    {
        
return  m_file;
    }

    LPCTSTR TempFileName() 
throw ()
    {
        
return  m_szTempFileName;
    }

private :
    CAtlFile m_file;
    TCHAR m_szTempFileName[_MAX_FNAME
+ 1 ];
    DWORD m_dwAccess;
};

typedef CAtlTemporaryFileExT
< false >  CAtlTemporaryFileEx;

// 自动删除版本
typedef CAtlTemporaryFileExT < true >  CAtlTemporaryFileExHandle;

你可能感兴趣的:(temporary)