zoukankan      html  css  js  c++  java
  • 无语的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;
  • 相关阅读:
    SQL SERVER常用函数
    SQL SERVER系统表
    How do I implement a cancelable event?
    sql之left join、right join、inner join的区别
    inno setup脚本,涵盖了自定义安装界面,调用dll等等应用
    MS SQL SERVER 数据库日志压缩方法与代码
    SQLSERVER:计算数据库中各个表的数据量和每行记录所占用空间
    mysql记录执行的SQL语句
    powershell 激活WIN10
    jfinal undertow web.xml
  • 原文地址:https://www.cnblogs.com/fangkm/p/1449907.html
Copyright © 2011-2022 走看看