利用Java的I/O流实现图片的压缩以及解压

文件压缩:

public class TestMerge {

    public static void merge(String srcFiles, String destFilePath) {
    	//判断原文件路径是否为空
        if (srcFiles == null) {
            throw new IllegalArgumentException(srcFiles + " must be not null");
        }
        //创建目标文件夹,并且判断目标文件夹是否存在
        File destFile = new File(destFilePath);
        if (!destFile.exists()) {
            boolean effect = destFile.mkdirs();
            if (!effect) {
                throw new IllegalArgumentException(destFile + " create failed");
            }
        }
        //获取原文件夹中所有的文件
        File[] files = listAllFiles(srcFiles);
        for (File src : files) {
			//如果文件格式不是jpg或者png,就不参与文件合并
            if (!src.getName().endsWith("jpg") && !src.getName().endsWith("png")) {
                continue;
            }
            //记录每个参与合并的文件的字节长度
            int length = (int) src.length();
			//进行文件传入和目的文件的传出
            try (FileInputStream in = new FileInputStream(src);
                 FileOutputStream out = new FileOutputStream(new File(destFile, "mergeP2.jpg"), true)) {
                //将每个参与合并的图片文件的长度加在文件字节前,用于记录参与合并的文件长度,并且在解压文件时起到指示此文件解压完成的作用
                //这里需要将文件的长度转换成byte数组,再传入目的文件中
                //length -> byte[]   82(int) -> 32(bit)
                for (int i = 0; i < trans(length).length; i++) {
//                    System.out.println(trans(length)[i]);
                    out.write(trans(length)[i]);
                }
                //读取原文件中的字节内容
                byte[] buff = new byte[1024];
                int len = -1;
                while ((len = in.read(buff)) != -1) {
                    out.write(buff, 0, len);
                }
                out.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

	//实现int类型转换为byte数组
    public static byte[] trans(int data) {
        //int转换成byte[] 不需要 & 0xFF
        //0xFF是字面量:00000000 00000000 00000000 11111111
        byte[] ret = new byte[4];
        ret[0] = (byte) (data >> 24);
        ret[1] = (byte) (data >> 16);
        ret[2] = (byte) (data >> 8);
        ret[3] = (byte) data;
        return ret;
    }

	//实现byte数组转换成int类型
    public static int byteArrayToInt(byte[] buff) {
        //byte[] 转换成int 必须 & 0xFF
        int values = 0;
        for (int i = 0; i < 4; i++) {
            int shift = (3 - i) * 8;
            values += (buff[i] & 0xFF) << shift;
        }
        return values;
    }

	//用来显示原文件夹下所有的文件,简化添加图片文件的步骤
    public static File[] listAllFiles(String srcFilePath) {
        File srcFile = new File(srcFilePath);
        if (srcFile.isFile()) {
            return new File[]{srcFile};
        }
        return srcFile.listFiles();
    }

	//测试
    public static void main(String[] args) {
//        String[] srcFiles = {"D:" + File.separator + "TestCode" + File.separator + "iotest" + File.separator + "data-a.txt",
//                "D:" + File.separator + "TestCode" + File.separator + "iotest" + File.separator + "data-b.txt",
//                "D:" + File.separator + "TestCode" + File.separator + "iotest" + File.separator + "data-c.txt"};
//        String destFilePath = "D:" + File.separator + "TestCode" + File.separator + "iotest" + File.separator + "data.txt";
//        merge(srcFiles, destFilePath);

        String srcFiles = "D:" + File.separator + "TestCode" + File.separator + "iotest" + File.separator + "spiltP";
        String destFilePath = "D:" + File.separator + "TestCode" + File.separator + "iotest" + File.separator + "mergePicture";
        long start = System.currentTimeMillis();
        merge(srcFiles, destFilePath);
        long end = System.currentTimeMillis();
        System.out.println(end-start);

    }
}

文件解压:

public class TestSplit {
    public static void splitFile(String srcFilePath, String destFilesPath) {
    	//判断原文件路径是否存在
        if (srcFilePath.isEmpty()) {
            throw new IllegalArgumentException(srcFilePath + "must be not null");
        }
        
        //创建原文件
        File srcFile = new File(srcFilePath);
        	//count用来记录解压得到的文件个数,并用于文件命名
            int count = 1;
            //创建目的文件夹
            File destFile = new File(destFilesPath);
            //判断目的文件夹是否存在
            if (!destFile.exists()) {
                destFile.mkdirs();
            }
            //进行文件传输
            try (FileInputStream in = new FileInputStream(srcFile)) {
                while (true) {
                	//首先读取压缩文件中的前4个字节,这4个字节记录了第一个解压出的文件长度
                    byte[] data = new byte[4];
                    int length = in.read(data);
                    if (length != 4) {
                        break;
                    }
                    //创建解压出的文件
                    FileOutputStream out = new FileOutputStream(new File(destFile, "p" + (count++) + ".jpg"));
                    //将压缩文件中的前四个字节记录的值转换成int类型的文件长度值
                    int fileLen = TestMerge.byteArrayToInt(data);
                    int len = -1;
                    //创建byte数组,数组长度为文件长度值
                    byte[] buff = new byte[fileLen];
                    len = in.read(buff);
                    //判断文件是否读取完
                    if (len != -1 && len == buff.length) {
                        //buff -> file
                        out.write(buff, 0, len);
                        out.flush();
                        out.close();
                        continue;
                    }
                    if (len == -1) {
                        break;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

	//测试
    public static void main(String[] args) {
        String directory = "D:" + File.separator + "TestCode" + File.separator + "iotest" + File.separator;
        String srcFilePath = directory + "mergePicture"+File.separator+"mergeP2.jpg";
        String destFilesPath = directory + "b";
        long start = System.currentTimeMillis();
        splitFile(srcFilePath, destFilesPath);
        long end = System.currentTimeMillis();
        System.out.println(end-start);
    }
}

运行结果:

测试用例中,合并了87个文件图片,总共大小为328389KB,测试结果如图:
压缩结果以及压缩时间:
在这里插入图片描述
在这里插入图片描述
解压结果以及解压时间:
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值