未能解决bug之java.io.IOException: Not in GZIP format

           问题描述: 今天遇到个奇怪的bug:java.io.IOException: Not in GZIP format

           源码呈现: 

package com.beyond.hibernate.common;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * @SystemName:压缩、解压缩工具类
 * @author ZX
 * @version V1.0
 * @Description: 将一传来的字串按照zip方式压缩和解压缩
 */
public class ZIPUtil {

 /**
  * @Title: compressByte
  * @author ZX
  * @param param
  * @return byte[]
  * @throws IOException
  */

 public static byte[] compressByte(String param) throws IOException {
  if (param == null || param.length() == 0) {
   return null;
  }
  ByteArrayOutputStream byteOut = null;
  GZIPOutputStream gzipOut = null;
  byte[] outPut = null;
  try {
   // 开启数据输出流,关闭无效
   byteOut = new ByteArrayOutputStream();
   // 开启数据压缩流
   gzipOut = new GZIPOutputStream(byteOut);
   // 将字串转换成字节,然后按照UTF-8的形式压缩
   gzipOut.write(param.getBytes("UTF-8"));
   // 压缩完毕
   gzipOut.finish();
   gzipOut.close();
   // 将压缩好的流转换到byte数组中去
   outPut = byteOut.toByteArray();
   byteOut.flush();
   byteOut.close();
  } finally {
   if (byteOut != null) {
    byteOut.close();
   }
  }
  return outPut;
 }

 /**
  * @Title: uncompressByte
  * @author ZX
  * @param param
  * @return byte[]
  * @throws IOException
  */
 public static String uncompressByte(byte[] param) throws IOException {
  ByteArrayOutputStream out = null;
  ByteArrayInputStream in = null;
  GZIPInputStream gzip = null;
  byte[] b = null;
  try {
   // 创建输出流
   out = new ByteArrayOutputStream();
   // 创建输入流,并把传入的字串参数转码成ISO-8895-1
   in = new ByteArrayInputStream(param);
   // 创建压缩输入流,将大小默认为参数输入流大小
   gzip = new GZIPInputStream(in);
   // 创建byte数组用于接收解压后的流转化成byte数组
   byte[] byteArry = new byte[256];
   int n = -1;
   while ((n = gzip.read(byteArry)) != -1) {
    out.write(byteArry, 0, n);
   }
   // 转换数据
   b = out.toByteArray();
   out.flush();
  } finally {
   // 关闭压缩流资源
   if(out != null)
    out.close();
   if(gzip != null)
    gzip.close();
   if(in != null)
    in.close();
  }
  return new String(b,"UTF-8");
 }

 
 public static void main(String[] args) {
  String param = "beyond ,come on ,you can do it !";
  String str = "", st = "";
  try {
   str = new String(ZIPUtil.compressByte(param));
   st = new String(ZIPUtil.uncompressByte(param.getBytes()));
  } catch (IOException e) {
   e.printStackTrace();
  }
  System.out.println(str);
  System.out.println("=======================");
  System.out.println(st);

 }

}

bug描述:

java.io.IOException: Not in GZIP format
 at java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:141)
 at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:56)
 at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:65)
 at com.beyond.hibernate.common.ZIPUtil.uncompressByte(ZIPUtil.java:73)
 at com.beyond.hibernate.common.ZIPUtil.main(ZIPUtil.java:122)

延迟解决原因:延迟处理。。。不知道怎么解决,发现这个bug应该和IO流底层有关

 

bug原因:是  st = new String(ZIPUtil.uncompressByte(param.getBytes()));调用时有问题,其中param.getBytes()在api中说是转换成的byte数组,但是这和uncompressByte(byte[])方法所要的参数byte[] 还不太一样,归根结底我认为是String中的Bytes()方法得到的byte[]和GZIPInputStream 所要的byte[] 不一样的,但是至于为何不一样?

这是由于String中的Bytes()方法得到的byte[]数组,而GZIPInputStream 所要的byte[]是一个流,为何这么说?如下:可以看出来这里的b是ByteArrayOutputStream流的toByteArray()方法得到的,里面的内容是流数据,而String中的Bytes()方法得到的byte[]内容是使用平台的默认字符集将此String 编码为 byte 序列,也就是编码后的字串内容成的byte[] 数组,经过   in = new ByteArrayInputStream(param);处理后成为流但是在 gzip = new GZIPInputStream(in);这一步就出错了,报错说是格式不对。。。到现在还没搞清楚是啥问题。。。。

 

临时解决方案:将结果单独列出来,其中写一句byte[] b = ZIPUtil.compressByte(param); 然后将b 传给ZIPUtil.uncompressByte(b); 数据结果是对的。

 

总结:byte[] 和 String方法getBytes() 在某些条件下是不能等同的

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值