目录
一、用Springboot读取本地工作目录的文件和文件结构
1.1、需求介绍
最近做项目时需要做一些云原生相关的内容,有个需求要在服务器上做临时文件夹作为工作目录,同时要将工作目录映射到docker image中和前端页面上。那么将服务器的本地工作目录渲染到前端页面上是必须要实现的部分,其中通过后端API读取本地目录,获取文件信息和文件系统层级数据是篇博客将要谈到的主要内容。
本篇博客不讲docker、不讲云原生,想要了解这方面知识的请关注我的其他博客,不了解这些知识的不影响阅读本文。
本文会从后端获取数据开始,还有一篇博客去讲如何通过后端获取的数据,使用el-tree将其在前端页面上渲染成美观的文件目录。
传送门:通过el-tree自定义渲染网页版工作目录,实现鼠标悬浮显示完整名称、用icon区分文件和文件夹等需求-CSDN博客
1.2、后端传递数据
1.2.1、语言框架
Java,Springboot。
1.2.2、本地工作目录示范
假设路径是:D:\workDirectory
根文件夹下的文件和文件夹信息如下图所示:
1.2.3、后端代码
①controller层
这里是项目额外写了个JsonResult的全局类,项目的所有API都用JsonResult类型来返回相应类型,其中包括响应状态码、响应信息以及响应数据。这里按照自己的需求来,或者直接改成List<Item>类型,直接返回最终数据也不是不行。
如下是简化的代码示范。其中WORKING_DIRECTORY是工作目录路径,是一个常量。实际应用可以和别的操作一起应用,比如上传操作执行后要重新读取一次本地目录,那么就可以在上传操作的API最后添加:
List<Item> directoryList = pythonEnvironmentalService.listDirectory(WORKING_DIRECTORY);
然后将directoryList作为返回值的一部分返回到前端,并实时渲染。
package edu.njnu.opengms.r2.domain.environmentalConfiguration; import edu.njnu.opengms.common.utils.JsonResult; import edu.njnu.opengms.common.utils.ResultUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; @RestController @RequestMapping(value = "/envs") public class EnvironmentalConfigurationController { @Autowired PythonEnvironmentalService pythonEnvironmentalService; // 定义静态常量来存储工作目录的路径 private static final String WORKING_DIRECTORY = "D:\\workDirectory"; //...其他的api方法 // 灵活接口,读取工作目录文件 @GetMapping("/getWorkDirectory") public JsonResult getDirectory() throws IOException { List<Item> directoryList = pythonEnvironmentalService.listDirectory(WORKING_DIRECTORY); return ResultUtils.success(directoryList); } }
按照这个例子,那么api就是ip+端口+/envs/getWorkDirectory。
②service层
简单讲一下吧,就是拿到要访问的目录之后,先扫描一遍,如果是文件,把文件的名称记录下来,如果是文件夹,就标记为文件夹,并递归调用这个方法,继续扫描子文件夹,直到层层扫描完毕,拿到所有文件和文件夹的名称和层级关系。如果需要文件的其他信息,请自行添加,逻辑是一样的,添加到item里面就行了。
// 访问本地目录文件夹的方法 public List<Item> listDirectory(String directory) throws IOException { Path path = Paths.get(directory); List<Item> items = new ArrayList<>(); try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)){ for (Path entry: stream) { boolean isDirectory = Files.isDirectory(entry); String name = entry.getFileName().toString(); List<Item> children = isDirectory ? listDirectory(entry.toString()) : new ArrayList<>(); items.add(new Item(name, children, isDirectory)); } } return items; }
③响应的数据
写完API,最好用postman测试一下,这里请求方式是get,用postman设置好请求方式和正确的路径就可以了。
以上述的本地工作目录为例,通过http://127.0.0.1:8082/envs/getWorkDirectory拿到的数据就是这样的(ip和端口按照实际情况来噢):
[ { "name": "clustering.py", "children": [], "directory": false }, { "name": "data", "children": [ { "name": "extrapolation_results.csv", "children": [], "directory": false } ], "directory": true }, { "name": "Dockerfile", "children": [], "directory": false }, { "name": "extrapolation_results.csv", "children": [], "directory": false }, { "name": "requirements.txt", "children": [], "directory": false }, { "name": "RooftopAreaConsolidationAndCalculation.py", "children": [], "directory": false }, { "name": "rooftop_area_360.csv", "children": [], "directory": false }, { "name": "test", "children": [ { "name": "1.1.txt", "children": [], "directory": false }, { "name": "test2", "children": [ { "name": "2.1.txt", "children": [], "directory": false } ], "directory": true } ], "directory": true } ]
通过postman测试没有问题之后,后端API就可以确定写好了,剩下的就是在前端进行数据渲染。具体操作和细节请关注我的其他博客。前端主要使用el-tree来渲染:Tree 树形控件 | Element Plus
二、总结
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~