我是靠谱客的博主 激情万宝路,这篇文章主要介绍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拿出数据后进行转型导致数据损坏,所以要么避免转型的操作,直接取出需要的字节数组类型的数据,要么使用不会损坏数据的转型方式。
最后
以上就是激情万宝路最近收集整理的关于GZIP在redis存取过程中出现 java.util.zip.ZipException: Not in GZIP format错误(已解决)的全部内容,更多相关GZIP在redis存取过程中出现内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复