无语的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;
posted @ 2009-05-05 14:35  孤竹君  阅读(557)  评论(0编辑  收藏  举报