• 递归创建文件和文件夹


    WIndows API函数CreateFile和CreateDirectory用于创建文件和目录,但设想这样一种情况:需要创建文件C:\test\test.txt,但是C:\test\目录不存在,简单地调用CreateFile不会成功了,创建目录也是一样。

    我在Windows API找了很久,没找到能满足要求的函数,Shell API里也没有,于是只能靠自己实现了。

    传入目录时,有些人习惯于在尾部加反斜杠,有些又没加反斜杠,为了方便编程,先封装一个方法来规范一下:

    //若bAddSpec 为真,则确保szDst路径末尾带有"\", 若bAddSpec为假,则去除lpszPath末尾的"\"或"/"
    template<size_t nSize>
    inline 
    void ModifyPathSpec( TCHAR (&szDst)[nSize], BOOL  bAddSpec )
    {
        
    int nLen = lstrlen( szDst );
        ASSERT( nLen 
    > 0 );
        TCHAR  ch  
    = szDst[ nLen - 1 ];
        
    if( ( ch == _T('\\') ) || ( ch == _T('/') ) )
        {
            
    if!bAddSpec )
            {
                szDst[ nLen 
    - 1 ] = _T('\0');
            }
        }
        
    else
        {
            
    if( bAddSpec )
            {
                szDst[ nLen ] 
    = _T('\\');
                szDst[ nLen 
    + 1 ] = _T('\0');
            }
        }
    }

    首先讨论创建文件夹的情况,创建文件夹时主要是个递归过程,首先判断上级目录是否存在,

    如果不存在,则递归创建上级目录.代码如下:

    //嵌套创建文件夹
    inline BOOL  CreateDirectoryNested( LPCTSTR  lpszDir )
    {
        
    if( ::PathIsDirectory( lpszDir ) ) return TRUE;

        TCHAR   szPreDir[ MAX_PATH ];
        _tcscpy_s( szPreDir, lpszDir );
        
    //确保路径末尾没有反斜杠
        ModifyPathSpec( szPreDir, FALSE );

        
    //获取上级目录
        BOOL  bGetPreDir  = ::PathRemoveFileSpec( szPreDir );
        
    if!bGetPreDir ) return FALSE;

        
    //如果上级目录不存在,则递归创建上级目录
        if!::PathIsDirectory( szPreDir ) )
        {
            CreateDirectoryNested( szPreDir );
        }

        
    return ::CreateDirectory( lpszDir, NULL );
    }
    创建文件目录后,直接调用CreateFile就可以创建文件了.代码如下:
    //嵌套创建文件,bOverride为TRUE表示覆盖原已存在的文件
    inline BOOL  CreateFileNested( LPCTSTR lpszFile, BOOL bOverride = TRUE )
    {
        
    if( ::PathFileExists( lpszFile ) )return TRUE;

        TCHAR   szDir[ MAX_PATH ];
        _tcscpy_s( szDir, lpszFile );

        
    //获取文件目录
        BOOL  bGetDir  = ::PathRemoveFileSpec( szDir );
        
    if!bGetDir )return FALSE;

        
    //创建文件目录
        if!CreateDirectoryNested( szDir ) )return FALSE;

        DWORD  dwCreate 
    =  bOverride?CREATE_ALWAYS:OPEN_ALWAYS;
        HANDLE hFile 
    = ::CreateFile( lpszFile, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
            dwCreate, FILE_FLAG_BACKUP_SEMANTICS, NULL );

        
    if( hFile == INVALID_HANDLE_VALUE)
            
    return FALSE;

        ::CloseHandle( hFile );
        
    return TRUE;
    }
  • 相关阅读:
    vue 拖拽移动(类似于iPhone虚拟home )
    鼠标事件-MouseEvent【转】
    JS快速排序 希尔排序 归并排序 选择排序
    JS 继承
    Centos6 iptables 防火墙设置【转】
    centos6 mongodb 安装
    操作系统中涉及的各种调度算法
    循环队列
    队列
    栈(C++)
  • 原文地址:https://www.cnblogs.com/fangkm/p/1426528.html
Copyright © 2020-2023  润新知