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

2022-08-08 13:45:36

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

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

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

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

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

/**
	 * 普通缓存获取
	 * 
	 * @param key 键
	 * @return 值
	 */publicObjectget(String key){return key==null?null: redisTemplate.opsForValue().get(key);}/**
	 * 普通缓存放入
	 * 
	 * @param key   键
	 * @param value 值
	 * @return true成功 false失败
	 */publicbooleanset(String key,Object value){try{
			redisTemplate.opsForValue().set(key, value);returntrue;}catch(Exception e){
			e.printStackTrace();returnfalse;}}

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

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

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

//压缩数据byte[] bytes=newCompressRedis().serialize(data);ByteArrayOutputStream baos=newByteArrayOutputStream();ObjectOutputStream oos=newObjectOutputStream(baos);
            oos.writeObject(bytes);//写入 RedisJedis jedis=newJedis();
            jedis.set((key.getBytes(), baos.toByteArray());//关闭流
            oos.close();// 读取 Byte格式 存入的数据ByteArrayInputStream byteArrayInputStream=newByteArrayInputStream(jedis.get(key.getBytes()));ObjectInputStream objectInputStream=newObjectInputStream(byteArrayInputStream);byte[] o=(byte[]) objectInputStream.readObject();//解压数据Object object=newCompressRedis().deserialize(p);

这便成功取出了数据

总结

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

  • 作者:CH·ST
  • 原文链接:https://blog.csdn.net/weixin_50074995/article/details/118696340
    更新时间:2022-08-08 13:45:36