GZIP在redis存取过程中出现 java.util.zip.ZipException: Not in GZIP format错误(已解决)

将数据压缩为GZIP格式存入redis再取出解压

在研究以GZIP格式压缩数据后进行redis存取操作以优化性能时遇到了这个问题

数据压缩为GZIP格式后是byte数组的形式,而在使用GZIP进行压缩,创建GZIPOutputStream对象时,会调用一个writeHeader方法,此方法会在输出流中写入GZIP的头信息。

头部信息的前两个字节存储的是标识数据,如果这两个数据出了问题那就无法识别数据格式,就会出现 java.util.zip.ZipException: Not in GZIP format的错误

一开始使用的是项目中自带的redis工具类,使用RedisTemplate进行存储

/**
	 * 普通缓存获取
	 * 
	 * @param key 键
	 * @return 值
	 */
	public Object get(String key) {
		return key == null ? null : redisTemplate.opsForValue().get(key);
	}

	/**
	 * 普通缓存放入
	 * 
	 * @param key   键
	 * @param value 值
	 * @return true成功 false失败
	 */
	public boolean set(String key, Object value) {
		try {
			redisTemplate.opsForValue().set(key, value);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

以这种方式进行存储,在取出时都是以object的形式取出的,而我们需要取出的是byte数组,所以我在取出后先将其转为String类型后再转为字节数组。

但是在这个过程中破坏了GZIP数据的头部信息,使得无法对数据进行解压并报错。

所以为了省去转类型这个步骤以避免头部信息的损坏,因此使用了Jedis 进行存储,使得取出的数据之间就是byte数组。

			//压缩数据
			byte[] bytes = new CompressRedis().serialize(data);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(bytes);

            //写入 Redis
            Jedis jedis = new Jedis();
            jedis.set((key.getBytes(), baos.toByteArray());
            //关闭流
            oos.close();

            // 读取 Byte格式 存入的数据
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(jedis.get(key.getBytes()));
            ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
            byte[] o = (byte[]) objectInputStream.readObject();
            //解压数据
            Object object = new CompressRedis().deserialize(p);

这便成功取出了数据

总结

问题出在从redis拿出数据后进行转型导致数据损坏,所以要么避免转型的操作,直接取出需要的字节数组类型的数据,要么使用不会损坏数据的转型方式。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值