从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. 前端展示结果:
上一篇: 站长圈转风向标了 都玩自媒体了