c语言删除非空文件夹

rmdir

rmdir() 删除空的文件夹

unlink

unlink();

man page 的解释:

   unlink() deletes a name from the filesystem.  If that name was the last link to a file and no processes have the file open,
   the file is deleted and the space it was using is made available for reuse.

   If the name was the last link to a file but any processes still have the file open, the file will remain in existence until
   the last file descriptor referring to it is closed.

   If the name referred to a symbolic link, the link is removed.

   If  the name referred to a socket, FIFO, or device, the name for it is removed but processes which have the object open may continue to use it.

中文解释哈:

    unlink() 从文件系统删除一个文件, 如果文件是最后一个链接并且没有被某个进程打开, 这个文件将被删除, 他所占用的空间可以被重新利用。

    如果这个文件是最后一个链接但是有进程打开了, 那么这个文件会一直存在, 知道指向它的文件描述符全部关闭!

     如果是个软链接, 直接干死!

      如果是个socket, FIFO, device, 那么文件直接删除, 但是打开次文件的进程该咋用就咋用, 不耽误!!

remove

remove()

deletes a name from the file system. It calls unlink(2) for files, and rmdir(2) for directories.

怎么删除非空的目录

       #include <ftw.h>

       int nftw(const char *dirpath,
               int (*fn) (const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf),
               int nopenfd, int flags);

nftw()遍历位于文件夹dirpath下面的目录树,为每个树的节点调用一次fn()。默认情况下,当前目录总是先于其包含的文件和子目录被处理(先序遍历)。

为了避免调用进程的文件描述符被用尽,nopenfd指定了 nftw() 能够同时打开目录的最大数量。当搜索深度超过这个值,nftw() 将会变慢,因为目录必须被关掉和重新打开。nftw() 为目录树中的每一层至多使用一个文件描述符。

对于在树中发现的每个节点,nftw() 为其调用带四个参数的函数fn(),这四个参数为fpath,sb,typeflag和ftwbuf。fpath是节点的路径名,它可以表示为相对路径或者绝对路径,相对路径是相对调用进程的当前工作目录。sb是为fpath调用stat函数所返回的指向stat结构体的指针。typeflag是一个整型值,取下面其中一个值:

  • FTW_F fpath是一个普通文件。
  • FTW_D fpath是一个目录。
  • FTW_DNR fpath是一个不能被读的目录。
  • FTW_DP fpath是一个目录,并且 flag参数被指定为FTW_DEPTH。(如果flags没有被指定为FTW_DEPTH,那么访问目录时使用的typeflag总会是FTW_D。)路径fpath下的所有文件和子目录已经被处理过了。
  • FTW_NS 在不是符号链接的fpath上调用stat失败。可能的原因是调用者对父目录有读权限,所以文件名fpath可以被看到,但是没有执行权限,所以执行stat失败。由sb指向的缓存的内容是未定义的。
  • FTW_SL fpath是一个符号链接,flags被设置为FTW_PHYS。
  • FTW_SLN fpath是一个指向不存在的文件的符号链接。(只在FTW_PHYS未被设置的时候才会发生。)

当调用fn() 时 nftw() 为其提供的第四个参数是一个类型为FTW的结构体:

struct FTW 
{
   int base;
   int level;
};

英文说明:

int (*fn) (const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
#fpath    文件或者目录名字
#sb       对fpath 执行stat 后返回的 struct stat 结构体
#typeflag 
/*
       FTW_F  fpath is a regular file.

       FTW_D  fpath is a directory.

       FTW_DNR
              fpath is a directory which can't be read.

       FTW_DP fpath  is  a  directory,  and  FTW_DEPTH was specified in flags.  (If FTW_DEPTH was not specified in flags, then directories will always be visited with
              typeflag set to FTW_D.)  All of the files and subdirectories within fpath have been processed.

       FTW_NS The stat(2) call failed on fpath, which is not a symbolic link.  The probable cause for this is that the caller had read permission on the parent direc-
              tory, so that the filename fpath could be seen, but did not have execute permission, so that the file could not be reached for stat(2).

       FTW_SL fpath is a symbolic link, and FTW_PHYS was set in flags.

       FTW_SLN
              fpath is a symbolic link pointing to a nonexistent file.  (This occurs only if FTW_PHYS is not set.)



*/
#FTW
/*
       The fourth argument that nftw() supplies when calling fn() is a structure of type FTW:

           struct FTW {
               int base;
               int level;
           };
           */

base是在fpath中给定的路径名中的文件名(basename)的偏移量。level是fpath在目录树中相对于根节点的深度(dirpath的深度为0)。

为了让树的遍历停止,fn() 返回一个非0值;这个值将会成为 nftw() 的返回值。只要fn()返回值为0,nftw()将会继续遍历目录树,直到要么遍历完整个树,在这种情况下会返回0;要么遇到一个错误(比如malloc失败),在这种情况下返回-1。

因为nftw() 使用动态数据结构,遍历目录树时唯一的安全退出方法就是从fn() 返回一个非0值。为了让信号量终止遍历时不会造成内存泄露,让处理这设置一个全局的flag,由fn()对这个全局flag进行检查。不要使用longjmp,除非程序将会终止(terminate)。

nftw() 的flags 参数由下面的一个或者多个的flags进行或运算所形成:

  1. FTW_ACTIONRETVAL

(从 glibc 2.3.3开始支持)
如果这个特定的glibc的flag被设置,nftw() 会对从fn()返回的值进行不同处理。fn() 应该返回下面的值的其中一个:

			**FTW_CONTINUE**
				让nftw() 继续正常进行。
			**FTW_SKIP_SIBLINGS**
				如果fn() 返回这个值,当前节点的兄弟节点会被跳过,处理从父节点继续进行。
			**FTW_SKIP_SUBTREE**
				如果一个目录节点调用fn()(typeflag是FTW_D),这个返回值会阻止这个目录下的对象作为参数传递给fn()。nftw() 继续处理当前目录的下一个兄弟节点。
			**FTW_STOP**
					这会导致nftw() 立即返回FTW_STOP。
					其它返回值可以关联到未来的一些新的行为上;fn() 不应该返回除上面列出的值之外的其它值。
					为了从<ftw.h>中获取FTW_ACTIONRETVAL的定义,必须在Include任何头文件之前定义功能测试宏 _GNU_SOURCE。
  1. FTW_CHDIR

    如果设置了这个flag,在处理每个目录的内容之前,都会chdir(2)到这个目录。如果程序需要在fpath所在的某个目录做一些操作,这就是有用的。(指定这个flag不会对作为fn 参数fpath进行传递的路径名有影响。)

  2. FTW_DEPTH
    设置这个flag会进行后序遍历,也就是在处理完当前目录的内容和它的所有子目录之后才会调用fn() (默认情况下,每个目录在它的内容之前被处理。)

  3. FTW_MOUNT
    设置这个flag,就会停留在同一个文件系统中(也就是不会跨越挂载点)。

  4. FTW_PHYS
    设置这个flag,就不会跟随符号链接。(这是你想做的。)如果不设置这个flag,就会跟随符号链接,但是没有文件会被报告两次。
    如果FTW_PHYS没有被设置,但是设置了FTW_DEPTH,那么函数fn() 就永远不会被自己是自己子孙的目录调用到。

返回值
这些函数成功返回0,失败返回-1.

如果fn() 返回非0值,那么树的遍历被终止,fn() 的返回值被当作ftw() 和 nftw() 的返回值返回。

如果nftw() 的调用设置了FTW_ACTIONRETVAL flag,那么应该被fn() 使用的用来终止树的遍历的唯一一个非0值就是FTW_STOP,这个值作为nftw() 的执行结果被返回。

demo

#define _XOPEN_SOURCE 500  //此处千万不可忘记, 没有这个就是一堆错误
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <ftw.h>
#include <stdint.h>


int implementFunc(const char *fpath, const struct stat *sb, int typeflag, struct FTW *FTWbuff) {
/*
           S_IFMT     0170000   bit mask for the file type bit field

           S_IFSOCK   0140000   socket
           S_IFLNK    0120000   symbolic link
           S_IFREG    0100000   regular file
           S_IFBLK    0060000   block device
           S_IFDIR    0040000   directory
           S_IFCHR    0020000   character device
           S_IFIFO    0010000   FIFO

       Thus, to test for a regular file (for example), one could write:

           stat(pathname, &sb);
           if ((sb.st_mode & S_IFMT) == S_IFREG) {
               // Handle regular file 
           }
*/
	printf("fpath = %-40s\t", fpath);
	switch(sb->st_mode & S_IFMT) {
		case S_IFSOCK: printf("file catigary = S_IFSOCK\t\t");break;
		case S_IFLNK: printf("file catigary = S_IFLNK\t\t");break;
		case S_IFREG: printf("file catigary = S_IFREG\t\t");break;
		case S_IFBLK: printf("file catigary = S_IFBLK\t\t");break;
		case S_IFDIR: printf("file catigary = S_IFDIR\t\t");break;
		case S_IFCHR: printf("file catigary = S_IFCHR\t\t");break;
		case S_IFIFO: printf("file catigary = S_IFIFO\t\t");break;
		default: break;
	}
	printf("base = %d\t level = %d\n", FTWbuff->base, FTWbuff->level);
	return 0;
}


int main()
{
	nftw("/usr/g/ctuser/zlj", implementFunc, 50, FTW_DEPTH|FTW_PHYS);
	return 0;
}

删除文件夹

#define _XOPEN_SOURCE 500
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <ftw.h>
#include <stdint.h>


int implementFunc(const char *fpath, const struct stat *sb, int typeflag, struct FTW *FTWbuff) {
    int status;
    int (*rmFunc)( const char * );

    switch(typeflag) {
        case FTW_DP: rmFunc = rmdir;  break;
        default:     rmFunc = unlink; break;
    }
    if(status = rmFunc(fpath), status != 0)
        perror(fpath);
    else
        puts(fpath);
    return status;
}


int main()
{
	nftw("/usr/g/ctuser/zlj", implementFunc, 50, FTW_DEPTH|FTW_PHYS);
	return 0;
}

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值