最近项目有个需求,上传一个文件压缩包,解压后根据解压的相对路径生成目录结构返回给前端展示,前端采用 element-ui 的el-tree组件,组件详情查看:el-tree
查阅相关资料发现生成目录树很多都是采用从数据库中读取目录关联结构生成的,但是在实际项目中没有相关的层次关系,需要建立层级结构,那么如何通过目录结构直接生成树状结构呢?
首先看下生成效果:
首先建立节点类:
节点包含节点id,文件名称,文件路径,父节点id,还有孩子节点列表
public class Menu {
public Integer id;
public String name;
public String path;
public Integer parentId;
public List
递归查询子节点:
private static ListgetChildrens(Menu root, List all) { List children = all.stream().filter(m -> { return Objects.equals(m.getParentId(), root.getId()); }).map((m) -> { m.setChildList(getChildrens(m, all)); return m; } ).collect(Collectors.toList()); return children; }
生成目录结构:
public static ListgetFilePathTree(List paths) { Map map = new LinkedHashMap<>(); Integer id = 1; for (int i = 0; i < paths.size(); i++) { String[] path = paths.get(i).split("/"); String p = ""; for (int j = 0; j < path.length; j++) { p += path[j] + "/"; if (!map.containsKey(p.substring(0, p.length() - 1))) { map.put(p.substring(0, p.length() - 1), id++); } } } List menus = new ArrayList<>(); for (Map.Entry entry : map.entrySet()) { Menu menu = new Menu(); Integer values = entry.getValue(); String[] keys = entry.getKey().split("/"); menu.setId(values); if (keys.length == 1) { menu.setParentId(0); menu.setName(keys[0]); menu.setPath(keys[0]); } else { String path = ""; for (int i = 0; i < keys.length - 1; i++) { path += keys[i] + "/"; } menu.setName(keys[keys.length - 1]); menu.setPath(String.join("/", keys)); path = path.substring(0, path.length() - 1); menu.setParentId(map.get(path)); } menus.add(menu); } //获取父节点 List collect = menus.stream().filter(m -> m.getParentId() == 0).map( (m) -> { m.setChildList(getChildrens(m, menus)); return m; } ).collect(Collectors.toList()); return collect; }
使用方式:
// 文件目录相对路径列子
private static String[] fileList = new String[]{
"dist/favicon.ico",
"dist/index.html",
"dist/static/css/app.46c00deb.css",
"dist/static/css/chunk-vendors.b80cec6e.css",
"dist/static/css/dashboard.65e4cda8.css",
"dist/static/css/home.c7bb3066.css",
"dist/static/css/login.89e00d4a.css",
"dist/static/css/table.cf6aa91f.css",
"dist/static/fonts/element-icons.535877f5.woff",
"dist/static/fonts/element-icons.732389de.ttf",
"dist/static/img/img.146655c9.jpg",
"dist/static/img/login-bg.e2134055.jpg",
"dist/static/js/app.db875c52.js",
"dist/static/js/chunk-vendors.31d72191.js",
"dist/static/js/dashboard.988c89e7.js",
"dist/static/js/home.482bfd24.js",
"dist/static/js/login.78ac76b0.js",
"dist/static/js/table.eac1b16a.js",
"dist/table.json"
};
public static void main(String args[]) throws IOException {
List collect = getFilePathTree(Arrays.asList(fileList));
System.out.println("-------转json输出结果-------");
System.out.println(JSON.toJSON(collect));
}
输出结果:
[{
"path": "dist",
"name": "dist",
"childList": [{
"path": "dist/favicon.ico",
"name": "favicon.ico",
"childList": [],
"id": 2,
"parentId": 1
}, {
"path": "dist/index.html",
"name": "index.html",
"childList": [],
"id": 3,
"parentId": 1
}, {
"path": "dist/static",
"name": "static",
"childList": [{
"path": "dist/static/css",
"name": "css",
"childList": [{
"path": "dist/static/css/app.46c00deb.css",
"name": "app.46c00deb.css",
"childList": [],
"id": 6,
"parentId": 5
}, {
"path": "dist/static/css/chunk-vendors.b80cec6e.css",
"name": "chunk-vendors.b80cec6e.css",
"childList": [],
"id": 7,
"parentId": 5
}, {
"path": "dist/static/css/dashboard.65e4cda8.css",
"name": "dashboard.65e4cda8.css",
"childList": [],
"id": 8,
"parentId": 5
}, {
"path": "dist/static/css/home.c7bb3066.css",
"name": "home.c7bb3066.css",
"childList": [],
"id": 9,
"parentId": 5
}, {
"path": "dist/static/css/login.89e00d4a.css",
"name": "login.89e00d4a.css",
"childList": [],
"id": 10,
"parentId": 5
}, {
"path": "dist/static/css/table.cf6aa91f.css",
"name": "table.cf6aa91f.css",
"childList": [],
"id": 11,
"parentId": 5
}],
"id": 5,
"parentId": 4
}, {
"path": "dist/static/fonts",
"name": "fonts",
"childList": [{
"path": "dist/static/fonts/element-icons.535877f5.woff",
"name": "element-icons.535877f5.woff",
"childList": [],
"id": 13,
"parentId": 12
}, {
"path": "dist/static/fonts/element-icons.732389de.ttf",
"name": "element-icons.732389de.ttf",
"childList": [],
"id": 14,
"parentId": 12
}],
"id": 12,
"parentId": 4
}, {
"path": "dist/static/img",
"name": "img",
"childList": [{
"path": "dist/static/img/img.146655c9.jpg",
"name": "img.146655c9.jpg",
"childList": [],
"id": 16,
"parentId": 15
}, {
"path": "dist/static/img/login-bg.e2134055.jpg",
"name": "login-bg.e2134055.jpg",
"childList": [],
"id": 17,
"parentId": 15
}],
"id": 15,
"parentId": 4
}, {
"path": "dist/static/js",
"name": "js",
"childList": [{
"path": "dist/static/js/app.db875c52.js",
"name": "app.db875c52.js",
"childList": [],
"id": 19,
"parentId": 18
}, {
"path": "dist/static/js/chunk-vendors.31d72191.js",
"name": "chunk-vendors.31d72191.js",
"childList": [],
"id": 20,
"parentId": 18
}, {
"path": "dist/static/js/dashboard.988c89e7.js",
"name": "dashboard.988c89e7.js",
"childList": [],
"id": 21,
"parentId": 18
}, {
"path": "dist/static/js/home.482bfd24.js",
"name": "home.482bfd24.js",
"childList": [],
"id": 22,
"parentId": 18
}, {
"path": "dist/static/js/login.78ac76b0.js",
"name": "login.78ac76b0.js",
"childList": [],
"id": 23,
"parentId": 18
}, {
"path": "dist/static/js/table.eac1b16a.js",
"name": "table.eac1b16a.js",
"childList": [],
"id": 24,
"parentId": 18
}],
"id": 18,
"parentId": 4
}],
"id": 4,
"parentId": 1
}, {
"path": "dist/table.json",
"name": "table.json",
"childList": [],
"id": 25,
"parentId": 1
}],
"id": 1,
"parentId": 0
}]
前端使用:
fileTree就是上面生成的json串
{{ data.name }} 删除
这样就可以生成相关目录结构树效果了



