欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

从linux下获取的文件目录字符串列表,转换成树形结构展示到前端

程序员文章站 2022-04-27 08:55:11
...

需求:

        需要从linux下获取递归获取指定目录下的所有子目录,然后将数据发送给后端,处理成树形结构数据展示在前端

 

1. 首先在Linux下通过shell脚本获取数据,并通过kafka发送到后端

##############################################################################
#read_dir()
##############################################################################
#功能说明: 递归获取指定目录下的所有目录
#参数说明: 指定目录
##############################################################################
function read_dir(){
    # ls获取指定目录下所有文件并遍历
    for file in `ls $1`
    do
        # 判断是不是目录,-d:如果是目录,则为真;-e:如果存在,则为真;-f:如果是常规文件,则为真;-z:如果string长度为0,则为真;-n:如果string长度非0,则为真
        if [ -d $1"/"$file ];
        then
            # 将文件目录信息写入pre_compile_dirs文件进行记录
            echo $1"/"$file >> pre_compile_dirs.txt
            # 递归查询
            read_dir $1"/"$file
        fi
    done
}



#遍历获取目录,并存储到当前目录的一个临时文件
read_dir $(pwd)


#定义字符串存储从文件中读取到的数据
dir_str=""
#读取文件内容
for line in `cat pre_compile_dirs.txt`
do
  dir_str="$dir_str$line "
done

#发送kafka消息,这里用了一个自己封装的公告方法,就不写了,具体逻辑可以自己实现
message="{dirStr:\"$dir_str\"}"
kafka_sender "$message" "kafka-topic-test"
if [ $? -eq 0 ]; then
	echo "成功发送到Kafka!"
else
	echo "error" "发送到Kafka失败!"
        exit 1
fi

#删除临时存储数据的文件
rm -rf pre_compile_dirs.txt

2. 后端接收到数据,处理数据,并存入数据库,这里过于简单,就不写具体逻辑了,存入数据库的数据结构为:

src
src/assembly
src/assembly/bin
src/main
src/main/java
src/main/java/com
src/main/java/com/test
src/main/java/com/test/jacoco
src/main/java/com/test/jacoco/config
src/main/java/com/test/jacoco/constant
src/main/java/com/test/jacoco/controller
src/main/java/com/test/jacoco/controller/hello
src/main/java/com/test/jacoco/model
src/main/java/com/test/jacoco/service
src/main/java/com/test/jacoco/service/hello
src/main/java/com/test/jacoco/service/hello/impl
src/main/java/com/test/jacoco/utils
src/main/profiles
src/main/profiles/beta
src/main/profiles/dev
src/main/profiles/product
src/main/resources
src/test
src/test/java
src/test/java/com
src/test/java/com/test
src/test/java/com/test/jacoco
target
target/archive-tmp
target/classes
target/classes/com
target/classes/com/test
target/classes/com/test/jacoco
target/classes/com/test/jacoco/config
target/classes/com/test/jacoco/constant
target/classes/com/test/jacoco/controller
target/classes/com/test/jacoco/controller/hello
target/classes/com/test/jacoco/model
target/classes/com/test/jacoco/service
target/classes/com/test/jacoco/service/hello
target/classes/com/test/jacoco/service/hello/impl
target/classes/com/test/jacoco/utils
target/generated-sources
target/generated-sources/annotations
target/maven-archiver
target/maven-status
target/maven-status/maven-compiler-plugin
target/maven-status/maven-compiler-plugin/compile
target/maven-status/maven-compiler-plugin/compile/default-compile
target/jacoco-distribution
target/jacoco-distribution/jacoco
target/jacoco-distribution/jacoco/bin
target/jacoco-distribution/jacoco/conf
target/jacoco-distribution/jacoco/lib

3. 查询字符串列表,将列表数据处理成树形数据,这里前端使用了element-ui的tree组件,所以要处理成下面结构:
 

data: [{
	  label: '一级 1',
	  children: [{
		label: '二级 1-1',
		children: [{
		  label: '三级 1-1-1'
		}]
	  }]
	}],
  };

4. 查询出列表后,由于列表存在重复节点,例如src/main 和 src/main/java,其实我只需要后面的src/main/java就可以,因为后面的包含了前面的所有节点,所以后端在处理时先去掉重复节点,然后再递归获取树形结构:

树形类:

public class DirTreeVo {

    private String label;

    private List<DirTreeVo> children;

    public DirTreeVo() {
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public List<DirTreeVo> getChildren() {
        return children;
    }

    public void setChildren(List<DirTreeVo> children) {
        this.children = children;
    }
}

递归处理:

public List<DirTreeVo> getDirs(Integer id) {
      //数据库查询获取数据
	List<String> pathList = mapper.getDirs(id);

      //第一步,处理存在重复节点的数据,因为linux递归获取目录,所以下面的目录肯定包含上面的目录,将列表倒序
	Collections.reverse(pathList);
      //建立新的列表和临时字符串
	List<String> paths = new ArrayList<>();
	String tempStr = "";

      //判断是否包含,如果不包含,就添加进入新的字符串,
	for (String path : pathList) {
		if (!tempStr.contains(path)) {
			tempStr += path;
			paths.add(path);
		}
	}

      //创建新的列表,用来存储返回树形数据
	List<DirTreeVo> dirTreeVos = new ArrayList<>();
      //递归处理列表数据为树形数据
	dealTree(paths, dirTreeVos);

	return dirTreeVos;
}


/**
 * 递归处理树形数据
 *
 * @param pathList
 * @param dirTreeVos
 * @author xxx
 * @date 2020/7/17
 */
private List<DirTreeVo> dealTree(List<String> pathList, List<DirTreeVo> dirTreeVos) {
	List<String> urlNoChild = pathList.stream().filter(dir -> !dir.contains("/")).collect(Collectors.toList());

	for (String path : urlNoChild) {
		DirTreeVo dirTreeVo = new DirTreeVo();
		dirTreeVo.setLabel(path);

		dirTreeVos.add(dirTreeVo);
	}

	//过滤出包含/的list
	List<String> urlContansChild = pathList.stream().filter(dir -> dir.contains("/")).collect(Collectors.toList());

	if (urlContansChild != null && urlContansChild.size() > 0) {
		//将存在/的路径分组
		Map<String, List<String>> hasChildMap = urlContansChild.stream()
				.collect(Collectors.groupingBy(item -> item.split("/")[0]));
		for (Map.Entry<String, List<String>> entry : hasChildMap.entrySet()) {
			//处理children
			List<String> childList = entry.getValue();

			//获取字列表数据
			childList = childList.stream().map(childPath -> childPath.substring(entry.getKey().length() + 1)).collect(Collectors.toList());

			//生成Tree
			DirTreeVo dirTreeVo = new DirTreeVo();
			dirTreeVo.setLabel(entry.getKey());

			//关键,设置children
			List<DirTreeVo> dirTreeVoList = new ArrayList<>();
			dirTreeVo.setChildren(dealTree(childList, dirTreeVoList));

			dirTreeVos.add(dirTreeVo);
		}
	}
	return dirTreeVos;
}

5. 前端展示结果:

从linux下获取的文件目录字符串列表,转换成树形结构展示到前端

相关标签: tree