dsg_01归档与解档

类型转换

整形转化为字节数组
思路
int 	1000
在电脑中的存储形式为:
0000 0000 0000 0000 0000 0011 1110 1000
转为字节数组为
arr[0] = 1110 1000 -> 10进制为-24(最前面一位是1说明他是负数,取反加一计算出它的十进制正值,就知道他的十负值)
arr[1] = 0000 0011 -> 10进制为3
arr[2] = 0000 0000 -> 10进制为0
arr[3] = 0000 0000 -> 10进制为0
代码实现
	public static byte[] int2Bytes(int i){
		//i的表现形式:0000 0000 0000 0000 0000 0011 1110 1000
        byte[] arr = new byte[4];
        //强转默认截掉前面的字节,保留最后一个字节
        //强转截取后:1110 1000
        arr[0] = (byte)i;
        //右移8位,把第二个字节放到最后一个字节上,强转默认截掉前面的字节,保留最后一个字节
        //右移8位:0000 0000 0000 0000 0000 0000 0000 0011
        //强转截取后:0000 0011
        arr[1] = (byte)(i >> 8);
        arr[2] = (byte)(i >> 16);
        arr[3] = (byte)(i >> 24);
        return arr;
    }
字节数组转化为整形
思路
int 	1000
在电脑中的字节数组为:
0000 0000 0000 0000 0000 0011 1110 1000
转为字节数组为
arr[0] = 1110 1000 -> 10进制为-24(最前面一位是1说明他是负数,取反加一计算出它的十进制正值,就知道他的十负值)
arr[1] = 0000 0011 -> 10进制为3
arr[2] = 0000 0000 -> 10进制为0
arr[3] = 0000 0000 -> 10进制为0
字节数组里面有负值,需要把负值转换为正值,但要保证字节的存储形式没有变化,与上-1并转为int类型即可,并且要让对应的字节回到属于它原本的位置
代码实现
	public static int Bytes2int(byte[] arr){
		//与上-1并隐式转换为int后:0000 0000 0000 0000 0000 0000 1110 1000
        int i0 = arr[0] & 0xFF;
        //与上-1并隐式转换为int后:0000 0000 0000 0000 0000 0000 0000 0011
        //左移8位后:0000 0000 0000 0000 0000 0011 0000 0000
        int i1 = (arr[1] & 0xFF) << 8;
        int i2 = (arr[2] & 0xFF) << 16;
        int i3 = (arr[3] & 0xFF) << 24;
        //或运算:
        // 0000 0000 0000 0000 0000 0000 1110 1000
        // 0000 0000 0000 0000 0000 0011 0000 0000
        // 0000 0000 0000 0000 0000 0011 1110 1000(结果)
        return i0 | i1 | i2 | i3;
    }

归档

作用: 归档就是把多个文件塞到一个文件里面去

	public static void main(String[] args) throws Exception {
        Archiver archiver = new Archiver();
        //归档是输出一个新的文件集合的过程,所以用输出流,如果以后想要一直往这个文件集合里塞东西,在参数里面再加个true
        FileOutputStream fis = new FileOutputStream("D:\\aa\\arch\\pic.xar",true);
        fis.write(archiver.arch("D:\\aa\\arch\\1.jpg"));
        fis.write(archiver.arch("D:\\aa\\arch\\2.jpg"));
        fis.write(archiver.arch("D:\\aa\\arch\\3.jpg"));
        fis.write(archiver.arch("D:\\aa\\arch\\4.jpg"));
        fis.write(archiver.arch("D:\\aa\\arch\\5.jpg"));
        fis.write(archiver.arch("D:\\aa\\arch\\6.jpg"));
        fis.close();
    }

    public byte[] arch(String path) throws Exception {
        File file = new File(path);
        //获取文件名
        String fileName = file.getName();
        //获取文件名的字节数组
        byte[] fileNameBytes = fileName.getBytes();
        //获取文件名长度的字节数组(整形转字节数组)
        byte[] fileNameBytesLength = Util.int2Bytes(fileNameBytes.length);
        //获取文件内容
        FileInputStream fis = new FileInputStream(file);
        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        //创建缓冲区
        byte[] b = new byte[1024];
        int len = 0;
        while ((len = fis.read(b)) != -1){
            bao.write(b,0,len);
        }
        fis.close();
        byte[] fileContentBytes = bao.toByteArray();
        //获取文件内容长度的字节数组
        byte[] fileContentBytesLength = Util.int2Bytes(fileContentBytes.length);
        //创建一个总字节数组
        //需要存储的东西:
        //1. 文件名的长度
        //2. 文件名
        //3. 文件内容的长度
        //4. 文件内容
        byte[] bytes = new byte[fileNameBytes.length + fileNameBytesLength.length + fileContentBytes.length + fileContentBytesLength.length];
        //写入文件名长度字节数组
        //参数:参数1:需要copy的数组A;参数2:copy的起始位置;参数3:存储的目标数组B;参数4:存储的起始位置;参数5:数组A存储的长度
        System.arraycopy(fileNameBytesLength,0,bytes,0,fileNameBytesLength.length);
        //写入文件名字节数组
        System.arraycopy(fileNameBytes,0,bytes,fileNameBytesLength.length,fileNameBytes.length);
        //写入文件内容长度字节数组
        System.arraycopy(fileContentBytesLength,0,bytes,fileNameBytesLength.length + fileNameBytes.length,fileContentBytesLength.length);
        //写入文件内容字节数组
        System.arraycopy(fileContentBytes,0,bytes,fileNameBytesLength.length + fileNameBytes.length + fileContentBytesLength.length,fileContentBytes.length);

        return bytes;
    }

解档

作用: 把归档文件解出来成一个个独立的文件

	public static void main(String[] args) throws Exception {
        List<Map<String, Object>> maps = new ArrayList<>();
        UnArchiver unArchiver = new UnArchiver();
        File file = new File("D:\\aa\\arch\\pic.xar");
        //解档需要读取归档文件,所以用输入流
        FileInputStream fis = new FileInputStream(file);
        Map<String, Object> map = null;
        //因为归档文件不止一个所以要循环遍历,直到读不到为止
        while ((map = unArchiver.readNextFile(fis)) != null){
            maps.add(map);
        }
        fis.close();
        
        //将归档文件遍历输出为一个个文件(解归档)
        FileOutputStream fos = null;
        for(Map<String, Object> map1:maps){
            fos = new FileOutputStream("D:\\aa\\arch\\unarch\\" + map1.get("fileName"));
            fos.write((byte[])map1.get("fileContent"));
            fos.close();
        }

    }

    public Map<String, Object> readNextFile(FileInputStream fis) throws Exception {
        //读取文件名的长度(长度是int类型,占4个字节,所以读取4个字节的数组即可)
        byte[] fileNameLengthBytes = new byte[4];
        int res = fis.read(fileNameLengthBytes);
        //如果读不到东西了,就要让程序停止
        if(res == -1){
            return null;
        }
        //将读到的字节数组转为整形就能得到文件名的长度,从而利用文件名的长度去读取文件名
        int fileNameLength = Util.Bytes2int(fileNameLengthBytes);
        //根据文件名的长度读取文件名
        byte[] fileNameBytes = new byte[fileNameLength];
        fis.read(fileNameBytes);
        String fileName = new String(fileNameBytes);
        //读取文件内容的长度
        byte[] fileContentBytesLength = new byte[4];
        fis.read(fileContentBytesLength);
        int fileContentLength = Util.Bytes2int(fileContentBytesLength);
        //根据文件内容的长度读取文件内容
        byte[] fileContentBytes = new byte[fileContentLength];
        fis.read(fileContentBytes);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("fileName",fileName);
        map.put("fileContent",fileContentBytes);
        return map;
    }

压缩

作用: 压缩是归档的一种,但是他可以缩小文件的大小(不一定,如果这个文件太小,压缩后反而会变大)

	public static void main(String[] args) throws Exception {
        //压缩与归档一样需要输出一个新的文件集合,所以使用输出流
        FileOutputStream fos = new FileOutputStream("D:\\aa\\arch\\pic.zip");
        //将输出流封装成压缩输出流
        ZipOutputStream zos = new ZipOutputStream(fos);
        //需要压缩的文件路径集合
        List<String> list = new ArrayList<>();
        list.add("D:\\aa\\arch\\1.jpg");
        list.add("D:\\aa\\arch\\2.jpg");
        list.add("D:\\aa\\arch\\3.jpg");
        list.add("D:\\aa\\arch\\4.jpg");
        list.add("D:\\aa\\arch\\5.jpg");
        list.add("D:\\aa\\arch\\6.jpg");
        list.add("D:\\aa\\arch\\pic.xar");
        list.add("D:\\aa\\arch\\ojdbc14.jar");
        for(String url:list){
            File file = new File(url);
            //设置压缩的这个文件的名字(一般保持原本的名字即可)
            zos.putNextEntry(new ZipEntry(file.getName()));
            //获取压缩文件的内容
            FileInputStream fis = new FileInputStream(file);
            byte[] bytes = new byte[fis.available()];
            fis.read(bytes);
            fis.close();
            //将压缩文件的内容写入压缩输出流中
            zos.write(bytes);
        }
        zos.close();
        fos.close();
    }

解压缩

作用: 把压缩文件解出来成一个个独立的文件

	public static void main(String[] args) throws Exception {
        //解压缩跟解档一样需要对压缩文件处理,所以需要获取压缩文件的输入流
        FileInputStream fis = new FileInputStream("D:\\aa\\arch\\pic.zip");
        //将输入流包装成压缩输入流
        ZipInputStream zis = new ZipInputStream(fis);
        ZipEntry zipEntry = null;
        int len = 0;
        byte[] bytes = new byte[1024];
        //遍历读取压缩输入流文件直到不能再读
        while ((zipEntry = zis.getNextEntry()) != null){
            //获取文件的名字
            String fileName = zipEntry.getName();
            //将输入流文件的内容输出到单个文件中去
            FileOutputStream fos = new FileOutputStream("D:\\aa\\arch\\pic\\" + fileName);
            while ((len = zis.read(bytes)) != -1){
                fos.write(bytes,0,len);
            }
            fos.close();
        }
        zis.close();
        fis.close();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值