Linux系统编程与网络编程——常用的目录操作函数,递归遍历目录(五)

mkdir 创建文件夹
在这里插入图片描述
递归创建文件夹

#include<stdio.h>
#include<unistd.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

int main(int argc, char** argv)
{
	if(argc < 2)
	{
		printf("usage: %s [dir]\n", argv[0]);
		return -1;
	} 
	int ret;
	char *buf, *p;
	buf = (char*)malloc(strlen(argv[1]) + 1);
	p = strtok(argv[1], "/");
	strcpy(buf, p);
	while(1)
	{
		printf("%s\n", buf);
		ret = mkdir(buf, 0755);
		if(ret == -1)
		{
			if(EEXIST != errno)
			{
				perror("mkdir");
				return -1;
			}
		}
 		p= strtok(NULL, "/");
		if(p == NULL)
			break;
		strcat(buf, "/");
		strcat(buf, p);
	} 
	return 0;
}

rmdir 删除文件夹
在这里插入图片描述


opendir打开文件夹
在这里插入图片描述
函数说明: opendir()用来打开参数name指定的目录,并返回DIR * 形态的目录流,和open()类似,接下来对目录的读取和搜索都要使用此返回值。

返回值: 成功则返回DIR * 型态的目录流,打开失败则返回NULL。
在这里插入图片描述


readdir读文件夹
在这里插入图片描述
函数说明: readdir()返回参数dir目录流的下个目录进入点。

返回值: 成功则返回下个目录进入点。有错误发生或读取到目录文件尾则返回NULL。EBADF参数dir为无效的目录流。
在这里插入图片描述

#include<sys/types.h>
#include<dirent.h>
#include<unistd.h>
#include <stdio.h>

int main()
{
	DIR *dir;
	struct dirent *ptr;
	int i;
	dir = opendir("/home/");
	while((ptr = readdir(dir))! = NULL)
	{
		printf("d_name: %s\n", ptr->d_name);
	} 
	closedir(dir);
}

输出如下:
在这里插入图片描述


rewinddir 重置读取目录的位置
在这里插入图片描述
函数说明: rewinddir()用来设置参数dir 目录流目前的读取位置为原来开头的读取位置。 错误码: EBADF参数dir为无效的目录流。

源码:rewinddir_test.c

#include<sys/types.h>
#include<dirent.h>
#include<unistd.h>
#include <stdio.h>

int main(void)
{
	DIR * dir;
	dir = opendir("/home/");
	while((ptr = readdir(dir))!=NULL)
	{
		printf("d_name :%s\n",ptr->d_name);
	} 
	/*重新遍历一次*/
	rewinddir(dir);
	printf("readdir again!\n");
	while((ptr = readdir(dir))!=NULL)
	{
		printf("d_name: %s\n",ptr->d_name);
	} 
	closedir(dir);
}

运行结果:
在这里插入图片描述


telldir、seekdir
在这里插入图片描述
函数说明: seekdir()用来设置参数dir目录流目前的读取位置,在调用readdir()时便从此新位置开始读取。参数offset 代表距离目录文件开头的偏移量。

telldir()返回参数dir目录流目前的读取位置。此返回值代表距离目录文件开头的偏移量,返回值返回下个读取位置,有错误发生时返回-1。

源码:tellseek_test.c

#include<sys/types.h>
#include<dirent.h>
#include<unistd.h>
#include <stdio.h>

int main(int argc, char**argv)
{
	DIR * dir;
	struct dirent * ptr;
	long offset,i = 0;
	if(argc < 2)
	{
		printf("Usage %s [file] \n", argv[0]);
		return -1;
	}
	dir = opendir(argv[1]);
	
	while((ptr = readdir(dir)) != NULL)
	{
		/*保存第二个记录项的偏移*/
		if(++i == 2)
		offset = telldir(dir);
		printf("d_name :%s\n", ptr->d_name);
	}
	
	/*重置目录指针到第二个记录项*/
	seekdir(dir, offset);
	printf("Readdir again!\n");
	while((ptr = readdir(dir))!=NULL)
	{
		printf("d_name :%s\n", ptr->d_name);
	}
	closedir(dir);
}

closedir
在这里插入图片描述


递归遍历目录

递归列出目录中的文件列表

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_PATH 1024

void fsize(char *name);

void Perror(char * title)
{
	perror(title);
	exit(-1);
}

void dirwalk(char *dir)
{
	char name[MAX_PATH];
	struct dirent *dp;
	DIR *dfd;
	if ((dfd = opendir(dir)) == NULL) { Perror("opendir"); }
	while ((dp = readdir(dfd)) != NULL)
	{
		if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
		continue;
		/*计算子目录路径字符串长度是否超长了*/
		if (strlen(dir)+strlen(dp->d_name)+2 > sizeof(name))
			printf("name %s %s too long\n",dir, dp->d_name);
		else
		{
			sprintf(name, "%s/%s", dir, dp->d_name);
			fsize(name);
		}
	} 
	closedir(dfd);
} 

void fsize(char *name)
{
	struct stat stbuf;
	if (stat(name, &stbuf) == -1) { Perror("stat"); }
	if (S_ISDIR(stbuf.st_mode))
	dirwalk(name);
	printf("%8ld %s\n", stbuf.st_size, name);
}

int main(int argc, char **argv)
{
	if(argc < 2)
	{
		printf("usage %s [file]\n", argv[0]);
		return -1;
	}
	if(argv[1][strlen(argv[1]) - 1] == '/')
	argv[1][strlen(argv[1]) - 1] = '\0';
	fsize(argv[1]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Gsunshine24/article/details/88955997