1. 1 不可撤销
  2. 2 小年兽 程嘉敏
  3. 3 手放开 李圣杰
  4. 4 迷人的危险3(翻自 dance flow) FAFA
  5. 5 山楂树之恋 程佳佳
  6. 6 summertime cinnamons / evening cinema
  7. 7 不谓侠(Cover 萧忆情Alex) CRITTY
  8. 8 神武醉相思(翻自 优我女团) 双笙
  9. 9 空山新雨后 音阙诗听 / 锦零
  10. 10 Wonderful U (Demo Version) AGA
  11. 11 广寒宫 丸子呦
  12. 12 陪我看日出 回音哥
  13. 13 春夏秋冬的你 王宇良
  14. 14 世界が终わるまでは… WANDS
  15. 15 多想在平庸的生活拥抱你 隔壁老樊
  16. 16 千禧 徐秉龙
  17. 17 我的一个道姑朋友 双笙
  18. 18 大鱼  (Cover 周深) 双笙
  19. 19 霜雪千年(Cover 洛天依 / 乐正绫) 双笙 / 封茗囧菌
  20. 20 云烟成雨(翻自 房东的猫) 周玥
  21. 21 情深深雨濛濛 杨胖雨
  22. 22 Five Hundred Miles Justin Timberlake / Carey Mulligan / Stark Sands
  23. 23 斑马斑马 房东的猫
  24. 24 See You Again Wiz Khalifa / Charlie Puth
  25. 25 Faded Alan Walker / Iselin Solheim
  26. 26 Natural J.Fla
  27. 27 New Soul Vox Angeli
  28. 28 ハレハレヤ(朗朗晴天)(翻自 v flower) 猫瑾
  29. 29 像鱼 王贰浪
  30. 30 Bye Bye Bye Lovestoned
  31. 31 Blame You 眠 / Lopu$
  32. 32 Believer J.Fla
  33. 33 书信 戴羽彤
  34. 34 柴 鱼 の c a l l i n g【已售】 幸子小姐拜托了
  35. 35 夜空中最亮的星(翻自 逃跑计划) 戴羽彤
  36. 36 慢慢喜欢你 LIve版(翻自 莫文蔚) 戴羽彤
  37. 37 病变(翻自 cubi) 戴羽彤
  38. 38 那女孩对我说 (完整版) Uu
  39. 39 绿色 陈雪凝
  40. 40 月牙湾 LIve版(翻自 F.I.R.) 戴羽彤
夜空中最亮的星(翻自 逃跑计划) - 戴羽彤
00:00 / 04:10

夜空中最亮的星 能否听清

那仰望的人 心底的孤独和叹息

夜空中最亮的星 能否记起

那曾与我同行 消失在风里的身影

我祈祷拥有一颗透明的心灵

和会流泪的眼睛

给我再去相信的勇气

越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请指引我靠近你

夜空中最亮的星 是否知道

那曾与我同行的身影 如今在哪里

夜空中最亮的星 是否在意

是等太阳先升起 还是意外先来临

我宁愿所有痛苦都留在心底

也不愿忘记你的眼睛

哦 给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行 哒~

我祈祷拥有一颗透明的心灵

和会流泪的眼睛 哦

给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行

2021.05.06 java实现文件压缩和解压

java作为一门相对比较完善的语言,有着特别丰富的接口和系统类,今天我们来看两个特殊的I/O流,这两个类可以协助我们实现文件的压缩和解压:GZIPOutputStream/GZIPInputStreamZipOutputStream/ZipInputStream,这两对压缩流都位于java.util.zip包下。这两个类,在web开发时也经常会用到,比如文件的批量上传和批量下载,所以掌握这两对流,可以有助于你很多web需求的实现。今天我们就来看下如何用他们来实现文件的压缩和解压。

GZ压缩

先上代码:

/**
     * 压缩gz
     * @param filePath
     * @return
     * @throws Exception
     */
    private static String compressFileByGZ(String filePath) throws Exception {
        File file = new File(filePath);
        System.out.println(file.getName());
        String outputFIleName = file.getName() + ".gz";
        GZIPOutputStream gzipOutputStream = new GZIPOutputStream(new FileOutputStream(outputFIleName));

        FileInputStream fileInputStream = new FileInputStream(filePath);
        byte[] bytes = new byte[1024];
        int read;
        while ((read = fileInputStream.read(bytes)) != -1) {
            gzipOutputStream.write(bytes);
        }
        fileInputStream.close();
        gzipOutputStream.close();

        return outputFIleName;
    }

GZ这里演示的只是单个文件的,多文件压缩从GZIP的接口来看,应该是不支持的,至少原生不支持,因为压缩包里面的文件名和GZ压缩包文件名是一致的,所以多文件压缩应该是有问题的,后面我再研究下,今天鉴于时间,就不深入了。压缩后的效果:

这里选了一张图片,压缩率43%,原文件大小为17kb,压缩后只有9.68kb

GZ解压

解压就是把压缩包里面的文件拿出来,相比于zipgz解压后的文件名只能取压缩文件的名字,因为它本身没有保留压缩的文件名。

/**
     * 解压GZ
     * @param filePath
     * @throws Exception
     */
    public static void extractGz(String filePath) throws Exception {
        FileInputStream fileInputStream = new FileInputStream(filePath);
        GZIPInputStream gzipInputStream = new GZIPInputStream(fileInputStream);
        FileOutputStream fileOutputStream = new FileOutputStream(new File(filePath).getName().replace(".gz", ""));
        byte[] bytes = new byte[1024];
        int x ;
        while ((x = gzipInputStream.read(bytes)) != -1) {
            fileOutputStream.write(bytes);
        }
        fileInputStream.close();
        gzipInputStream.close();
        fileOutputStream.close();
    }

解压后的文件:

ZIP压缩

zip的压缩就比较有意思了,原生支持多文件压缩,需要注意的是每个文件要单独创建一个ZipEntry,它就相当于压缩包里面每一个单独的文件,它包含被压缩文件的文件信息,所以解压的时候,可以拿到之前压缩的文件名。

/**
     * 压缩zip
     *
     * @param filePath
     * @return
     * @throws Exception
     */
    private static String compressFileByZIP(String filePath) throws Exception {
        File file = new File(filePath);
        System.out.println(file.getName());
        String outputFIleName = file.getName() + ".zip";
        ArrayList<File> fileList = new ArrayList<>();
        if (file.isDirectory()) {
            fileList.addAll(Arrays.asList(file.listFiles()));
        } else {
            fileList.add(file);
        }
        FileInputStream fileInputStream = null;
        CheckedOutputStream checkedOutputStream = new CheckedOutputStream(new FileOutputStream(outputFIleName), new Adler32());
        ZipOutputStream zipOutputStream = new ZipOutputStream(checkedOutputStream);
        for (File f : fileList) {
            if (f.isDirectory()) {
                continue;
            }
            zipOutputStream.putNextEntry(new ZipEntry(f.getName()));
            fileInputStream = new FileInputStream(f);
            byte[] bytes = new byte[1024];
            int read;
            while ((read = fileInputStream.read(bytes)) != -1) {
                zipOutputStream.write(bytes);
            }
        }
        byte[] bytes = new byte[1024];
        int read;
        while ((read = fileInputStream.read(bytes)) != -1) {
            zipOutputStream.write(bytes);
        }
        fileInputStream.close();
        zipOutputStream.close();

        return outputFIleName;
    }

zip本身就支持多文件,所以这里就演示了多文件压缩,单个文件也做了兼容。压缩文件效果:

被压缩文件夹,共212个文件

文件大小

压缩文件

压缩后34.8MB,和我电脑上安装的压缩软件做了对比,压缩后大小是一样的

ZIP解压

解压我们前面说了,它的ZipEntry包含被压缩文件的信息,所以就很简单了:

 /**
     * 解压zip文件
     * @param filePath
     * @return
     * @throws Exception
     */
    public static String extractZip(String filePath) throws Exception{
        FileInputStream fileInputStream = new FileInputStream(filePath);
        CheckedInputStream checkedInputStream = new CheckedInputStream(fileInputStream, new Adler32());
        ZipInputStream zipInputStream = new ZipInputStream(checkedInputStream);
        ZipEntry zipEntry;

        FileOutputStream fileOutputStream = null;
        File savePath = new File(filePath.replace(".zip", ""));
        if (!savePath.exists()) {
            savePath.mkdir();
        }
        BufferedInputStream bufferedInputStream = new BufferedInputStream(zipInputStream);
        while ((zipEntry = zipInputStream.getNextEntry()) != null) {
            fileOutputStream = new FileOutputStream(savePath.getName() + "/" + zipEntry.getName());
            int x;
            byte[] bytes = new byte[1024];
            while ((x = bufferedInputStream.read(bytes)) != -1) {
                fileOutputStream.write(bytes);
            }
            fileOutputStream.close();
        }
        zipInputStream.close();
        fileInputStream.close();
        return null;
    }

第一个循环是从流里面拿出压缩包中的每一个文件(zipEntry),第二个循环就是从流中把被压缩文件还原成压缩前的格式。

ZIP补充

这里要补充两点,一个是CheckedInputStream/CheckedOutputStream。这一对流是为各种流提供校验和的,也就是校验输出输入数据的;另一个也和CheckedOutputStream/CheckedInputStream有关,就是构建这两个流的时候传的Adler32在,这里其实表示的是计算和校验文件的校验和的方式(Checksum),取值有两种,分别是Adler32CRC32,但是因为Adler32更快,所以这里我们用了它,CRC32虽然慢,但也更准确。

总结

总的来说,java文件压缩和解压方面的内容还是比较简单的,主要涉及了I/O流方面的知识点,各位小伙伴只要掌握了上面两种压缩和解压的方式,大部分web端开发的压缩和解压需求也可以迎刃而解了,当然最重要的一点是,要自己动手做,不然就真的变成了:

眼睛:我会了……

手:那你来

眼睛:……

好了,大家晚安吧

项目路径:

https://github.com/Syske/example-everyday

本项目会每日更新,让我们一起学习,一起进步,遇见更好的自己,加油呀

posted @ 2021-05-09 15:38  云中志  阅读(357)  评论(0编辑  收藏  举报