使用ArrayListMultimap遍历文件生成文件树

该方法首先获取所有的文件和文件夹,然后根据父子关系遍历生成树形结构的文件列表。

一、相关方法介绍

1.ArrayListMultimap

官方文档描述如下:

This multimap allows duplicate key-value pairs. After adding a new key-value pair equal to an existing key-value pair, the {@code ArrayListMultimap} will contain entries for both the new value and the old value.
此多映射允许重复的键值对。添加与现有键值对相等的新键值对后,{@code ArrayListMultimap}将包含新值和旧值的条目。

也就是说,ArrayListMultimap是一个key到多个value的映射关系的数据结构,本质上还是Map。其常用方法如下:

//创建一键多值的ArrayListMultimap集合
ArrayListMultimap<String, String> mutimap = ArrayListMultimap.create();
//get方法和put方法
List<String> strings = mutimap.get("key");
fileMutimap.put("key", "value");
//keys方法和keySet方法
Multiset<String> keys = mutimap.keys();
Set<String> strings = fileMutimap.keySet();
//size方法
int size = fileMutimap.size();

2.Files.walkFileTree

为了方便直接使用该方法遍历文件,当然也可选择使用其他方法读取文件。
walkFileTree()包含用于递归遍历目录树的方法,方法参数接收一个Path对象和一个FileVisitor对象,Path对象指向需要遍历的目录FileVisitor在遍历的时候调用。FileVisitor接口定义了四个方法,调用时间如下:

  • preVisitDirectory():在访问任意目录前调用;
  • postVisitDirectory():在访问任意目录完成后调用;
  • visitFile():在访问到每个文件时调用;
  • visitFileFaild():在访问文件失败是调用

二、实例

为了方便,直接使用FileVO类和Controller类来展示代码逻辑。

1.FileVo类

根据目录结构创建文件实体类,目录应包含目录名,父目录名,文件列表和子目录列表。

@Data
public class FileVO {
    /**
     * 父目录,在传递给前端时忽略此字段
     */
    @JsonIgnore
    private String parent;
    
    /**
     * 目录名
     */
    private String directory;
    
    /**
     * 文件列表
     */
    private List<String> fileName;

    /**
     * 子目录
     */
    private List<FileVO> children;
}

2.Controller

@RestController
@RequestMapping(path = "/file")
public class FileController {
    @PostMapping("/getFiles")
    public List<FileVO> getFiles(String dir) throws IOException {
        //确定根节点
        String root = dir;
        //文件列表
        ArrayListMultimap<String, String> fileMutimap = ArrayListMultimap.create();
        //目录集合
        ArrayListMultimap<String, FileVO> dirMutimap = ArrayListMultimap.create();
        //根目录集合
        List<FileVO> ancestors = new ArrayList<>();
        Files.walkFileTree(Paths.get(dir), new SimpleFileVisitor<Path>() {
            //遍历文件
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                fileMutimap.put(file.getParent().toString(), file.getFileName().toString());
                return FileVisitResult.CONTINUE;
            }

            //遍历目录
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
                FileVO fileVO = new FileVO();
                String dirName = dir.toString();
                fileVO.setDirectory(dirName);
                fileVO.setParent(dir.getParent().toString());
                //填充文件到目录
                fileVO.setFileName(fileMutimap.get(dirName));
                //是否为根节点
                if (StringUtils.equals(dirName, root)) {
                    ancestors.add(fileVO);
                }
                dirMutimap.put(dir.getParent().toString(), fileVO);
                return FileVisitResult.CONTINUE;
            }
        });
        if (CollectionUtils.isNotEmpty(ancestors)) {
            for (FileVO ancestor : ancestors) {
                recursionBuild(dirMutimap, ancestor);
            }
        }
        return ancestors;
    }

    public void recursionBuild(ArrayListMultimap<String, FileVO> dirMultimap, FileVO ancestor) {
        List<FileVO> children = dirMultimap.get(ancestor.getDirectory());
        if (CollectionUtils.isEmpty(children)) {
            return;
        }
        ancestor.setChildren(children);
        for (FileVO child : children) {
            recursionBuild(dirMultimap, child);
        }
    }
}

三、postman测试结果

07eb3954d9ce455e98a37aa15b5b4842
[
    {
        "directory": "G:\\test",
        "fileName": [
            "aa.txt"
        ],
        "children": [
            {
                "directory": "G:\\test\\test01",
                "fileName": [
                    "test01_aa.jpg",
                    "test01_bb.jpg"
                ],
                "children": [
                    {
                        "directory": "G:\\test\\test01\\test03",
                        "fileName": [
                            "03_aa.jpg",
                            "03_bb.jpg"
                        ],
                        "children": null
                    }
                ]
            },
            {
                "directory": "G:\\test\\test02",
                "fileName": [
                    "test02_aa.jpg",
                    "test02_bb.jpg"
                ],
                "children": null
            }
        ]
    }
]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值