kkFileView代码分析(六)

2021SC@SDUSC

目录

读取zip文件

对zip实体进行排序

 添加节点

文件名倒数第二部分获取

FileNode属性


zip文件解压都封装在ZipUtils类中,先来分析zip文件的读取方法readZipFile()

读取zip文件

-filepath:文件路径

-filekey:文件标识

方法开头先创建如下变量:

        -map变量appender:方便以后存取数据

        -列表imgurl:存放解压出来的图片地址

        -字符串archiveFileName:获取压缩包的文件名

        之后进行一个try-catch语句,创建Enumeration<ZipArchiveEntry>变量entries存放压缩包zip的文件实体,调用自定义的sortZipEntries()方法对实体进行排序,并将排序完成后的entries存入队列entriesToBeExtracted。

        之后进入while循环,声明ZipArchiveEntry变量entry,赋值为zip文件中的文件实体,定义string-key为实体的文件名。文件名分为originName部分和chhildName部分,childName只有在文件不是目录directory的前提下才可赋值。调用getLast2FileNmae获取parentName。如果childName中的url-typr是图片,则将图片文件添加到图片列表中。

        最后开启新的线程处理文件解压。

    public String readZipFile(String filePath,String fileKey) {
        String archiveSeparator = "/";
        Map<String, FileNode> appender = Maps.newHashMap();
        List<String> imgUrls = Lists.newArrayList();
        String baseUrl = BaseUrlFilter.getBaseUrl();
        String archiveFileName = fileUtils.getFileNameFromPath(filePath);
        try {
            ZipFile zipFile = new ZipFile(filePath, fileUtils.getFileEncodeUTFGBK(filePath));
            Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
            // 排序
            entries = sortZipEntries(entries);
            List<Map<String, ZipArchiveEntry>> entriesToBeExtracted = Lists.newArrayList();
            while (entries.hasMoreElements()){
                ZipArchiveEntry entry = entries.nextElement();
                String fullName = entry.getName();
                int level = fullName.split(archiveSeparator).length;
                // 展示名
                String originName = getLastFileName(fullName, archiveSeparator);
                String childName = level + "_" + originName;
                boolean directory = entry.isDirectory();
                if (!directory) {
                    childName = archiveFileName + "_" + originName;
                    entriesToBeExtracted.add(Collections.singletonMap(childName, entry));
                }
                String parentName = getLast2FileName(fullName, archiveSeparator, archiveFileName);
                parentName = (level-1) + "_" + parentName;
                FileType type=fileUtils.typeFromUrl(childName);
                if (type.equals(FileType.picture)){//添加图片文件到图片列表
                    imgUrls.add(baseUrl+childName);
                }
                FileNode node = new FileNode(originName, childName, parentName, new ArrayList<>(), directory, fileKey);
                addNodes(appender, parentName, node);
                appender.put(childName, node);
            }
            // 开启新的线程处理文件解压
            executors.submit(new ZipExtractorWorker(entriesToBeExtracted, zipFile, filePath));
            fileUtils.putImgCache(fileKey,imgUrls);
            return new ObjectMapper().writeValueAsString(appender.get(""));
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

对zip实体进行排序

调用list的sort方法,使用java.util.Comparator 创建一个比较器调用comparingInt方法,sort 对象接收一个 Comparator 函数式接口,可以传入一个lambda表达式。放在这里指按照名字长度排序。

    private Enumeration<ZipArchiveEntry> sortZipEntries(Enumeration<ZipArchiveEntry> entries) {
        List<ZipArchiveEntry> sortedEntries = new LinkedList<>();
        while (entries.hasMoreElements()) {
            sortedEntries.add(entries.nextElement());
        }
        sortedEntries.sort(Comparator.comparingInt(o -> o.getName().length()));
        return Collections.enumeration(sortedEntries);
    }

 添加节点

        往传入参数appender中包含parentname的对象添加childname节点

    private void addNodes(Map<String, FileNode> appender, String parentName, FileNode node) {
        if (appender.containsKey(parentName)) {
            appender.get(parentName).getChildList().add(node);
            appender.get(parentName).getChildList().sort(sortComparator);
        } else {
            // 根节点
            FileNode nodeRoot = new FileNode(parentName, parentName, "", new ArrayList<>(), true);
            nodeRoot.getChildList().add(node);
            appender.put("", nodeRoot);
            appender.put(parentName, nodeRoot);
        }
    }

文件名倒数第二部分获取

    private static String getLast2FileName(String fullName, String seperator, String rootName) {
        if (fullName.endsWith(seperator)) {
            fullName = fullName.substring(0, fullName.length() - 1);
        }
        // 1.获取剩余部分
        int endIndex = fullName.lastIndexOf(seperator);
        String leftPath = fullName.substring(0, endIndex == -1 ? 0 : endIndex);
        if (leftPath.length() > 1) {
            // 2.获取倒数第二个
            return getLastFileName(leftPath, seperator);
        } else {
            return rootName;
        }
    }

FileNode属性

        分为目录(根节点)和普通节点,directory是用在zip中是文件时要寻址时用的。

        public FileNode(String originName, String fileName, String parentFileName, List<FileNode> childList, boolean directory) {
            this.originName = originName;
            this.fileName = fileName;
            this.parentFileName = parentFileName;
            this.childList = childList;
            this.directory = directory;
        }

        public FileNode(String originName, String fileName, String parentFileName, List<FileNode> childList, boolean directory, String fileKey) {
            this.originName = originName;
            this.fileName = fileName;
            this.parentFileName = parentFileName;
            this.childList = childList;
            this.directory = directory;
            this.fileKey = fileKey;
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值