最近项目中有一个采集数据的需求,上传数据时需要先讲数据压缩后进行上传,发现数据压缩失败,问题代码如下
public byte[] compress(String str) {
if (str==null || str.length() <= 0) {
return str.getBytes();
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip=null;
try{
gzip= new GZIPOutputStream(out);
gzip.write(str.getBytes());
return out.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
out.close();
gzip.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return str.getBytes();
}
后经过排查以后,发现是因为流的关闭顺序不对导致的,当一个流后被使用时,应该先被关闭,也就是需要先关闭GZIPOutputStream,再关闭ByteArrayOutputStream
修改后的代码:
public byte[] compress(String str) {
if (str==null || str.length() <= 0) {
return str.getBytes();
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip=null;
try{
gzip= new GZIPOutputStream(out);
gzip.write(str.getBytes());
return out.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
gzip.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return str.getBytes();
}
其实以上代码还是有问题,关闭流的时候,最好是每个流单独一个try catch进行关闭,但是Java7以后有一个特性,比较方便
代码如下:
public byte[] compress(String str) {
if (str==null || str.length() <= 0) {
return str.getBytes();
}
try( ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip= new GZIPOutputStream(out)
) {
gzip.write(str.getBytes());
return out.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return str.getBytes();
}
直接在try后面的括号里初始化流,会自行关闭,释放资源