java内置解压方法_java内置的解压缩工具

简介

java关于压缩和解压缩的核心类就是Defalter(压缩)类和Inflater(解压)类,操作GZip和Zip文件也是基于这两个类。Tomcat对响应数据的压缩就是基于GZip。

使用Deflater和Inflater解压缩

import java.io.BufferedInputStream;

import java.io.ByteArrayOutputStream;

import java.io.FileInputStream;

import java.io.InputStream;

import java.util.zip.Deflater;

import java.util.zip.Inflater;

public class Client {

public static void main(String[] args) throws Exception {

byte[] bytes = readFromFile("D:/testdeflate.txt");

System.out.println("before compress: " + bytes.length);

byte[] compressedBytes = compress(bytes);

System.out.println("after compress: " + compressedBytes.length);

byte[] decompressBytes = decompress(compressedBytes);

System.out.println("after decompress: " + decompressBytes.length);

}

/**

* 解压数据

*

* @param bytes 源数据

* @return 压缩之后的数据

*/

private static byte[] decompress(byte[] bytes) {

Inflater inflater = new Inflater();

//设置待解压数据

inflater.setInput(bytes);

byte[] buf = new byte[1024];

try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {

//是否已解压完成

while (!inflater.finished()) {

//解压

int len = inflater.inflate(buf);

output.write(buf, 0, len);

}

//关闭资源

inflater.end();

return output.toByteArray();

} catch (Exception e) {

e.printStackTrace();

}

return new byte[0];

}

/**

* 压缩数据

*

* @param bytes 源数据

* @return 压缩之后的数据

*/

private static byte[] compress(byte[] bytes) {

Deflater deflater = new Deflater();

//设置待压缩数据

deflater.setInput(bytes);

//表示压缩以当前输入内容结束,暂时不知道具体原理

deflater.finish();

byte[] buf = new byte[1024];

try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {

//是否已压缩完成

while (!deflater.finished()) {

//压缩

int len = deflater.deflate(buf);

output.write(buf, 0, len);

}

//关闭资源

deflater.end();

return output.toByteArray();

} catch (Exception e) {

e.printStackTrace();

}

return new byte[0];

}

/**

* 读取文件内容

*

* @param filePath 文件路径

* @return 文件内容

*/

private static byte[] readFromFile(String filePath) {

int len = -1;

byte[] buf = new byte[1024];

try (InputStream input = new BufferedInputStream(new FileInputStream(filePath));

ByteArrayOutputStream output = new ByteArrayOutputStream()) {

while ((len = input.read(buf)) != -1) {

output.write(buf, 0, len);

}

return output.toByteArray();

} catch (Exception e) {

e.printStackTrace();

}

return new byte[0];

}

}

输出结果为

before compress: 43435

after compress: 1168

after decompress: 43435

可以看到数据从原来的43435字节压缩到了1168字节。

使用DeflaterOutputStream和InflaterOutputStream解压缩

import java.io.BufferedInputStream;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.util.zip.DeflaterOutputStream;

import java.util.zip.InflaterInputStream;

public class Client {

public static void main(String[] args) throws IOException {

byte[] bytes = readFromFile("D:/testdeflate.txt");

System.out.println("before compress: " + bytes.length);

byte[] compressedBytes = readFromFileAndCompress("D:/testdeflate.txt");

System.out.println("after compress: " + compressedBytes.length);

byte[] decompressBytes = readAndDecompress(compressedBytes);

System.out.println("after decompress: " + decompressBytes.length);

}

/**

* 读取文件内容并压缩

*

* @param filePath 文件路径

* @return 文件内容

*/

private static byte[] readFromFileAndCompress(String filePath) {

int len = -1;

byte[] buf = new byte[1024];

try (InputStream input = new BufferedInputStream(new FileInputStream(filePath));

ByteArrayOutputStream output = new ByteArrayOutputStream();

DeflaterOutputStream dos = new DeflaterOutputStream(output)) {

//从输入流读取写入到输出流

while ((len = input.read(buf)) != -1) {

dos.write(buf, 0, len);

}

//必须

dos.finish();

return output.toByteArray();

} catch (Exception e) {

e.printStackTrace();

}

return new byte[0];

}

/**

* 读取文件内容

*

* @param filePath 文件路径

* @return 文件内容

*/

private static byte[] readFromFile(String filePath) {

int len = -1;

byte[] buf = new byte[1024];

try (InputStream input = new BufferedInputStream(new FileInputStream(filePath));

ByteArrayOutputStream output = new ByteArrayOutputStream()) {

while ((len = input.read(buf)) != -1) {

output.write(buf, 0, len);

}

return output.toByteArray();

} catch (Exception e) {

e.printStackTrace();

}

return new byte[0];

}

/**

* 读取并解压缩

*

* @param bytes 待解压数据

* @return 解压之后的数据

*/

private static byte[] readAndDecompress(byte[] bytes) {

int len = -1;

byte[] buf = new byte[1024];

try (InputStream input = new InflaterInputStream(new ByteArrayInputStream(bytes));

ByteArrayOutputStream output = new ByteArrayOutputStream()) {

while ((len = input.read(buf)) != -1) {

output.write(buf, 0, len);

}

return output.toByteArray();

} catch (IOException e) {

e.printStackTrace();

}

return new byte[0];

}

}

输出结果为

before compress: 43435

after compress: 1168

after decompress: 43435

可以看到和使用Deflater压缩的效果是一样的。DeflaterOutputStream写入完成之后必须调用finish()方法。

/**

* This class implements an output stream filter for compressing data in

* the "deflate" compression format. It is also used as the basis for other

* types of compression filters, such as GZIPOutputStream.

*

* @see Deflater

* @author David Connelly

* @since 1.1

*/

public

class DeflaterOutputStream extends FilterOutputStream {

/**

* 压缩类

*/

protected Deflater def;

/**

* 重写了父类的write方法,先将数据压缩再写入

*/

public void write(byte[] b, int off, int len) throws IOException {

if (def.finished()) {

throw new IOException("write beyond end of stream");

}

if ((off | len | (off + len) | (b.length - (off + len))) < 0) {

throw new IndexOutOfBoundsException();

} else if (len == 0) {

return;

}

if (!def.finished()) {

def.setInput(b, off, len);

while (!def.needsInput()) {

deflate();

}

}

}

/**

* 数据压缩

*/

protected void deflate() throws IOException {

int len = def.deflate(buf, 0, buf.length);

if (len > 0) {

out.write(buf, 0, len);

}

}

}

可以看到DeflaterOutputStream内部就是使用了Deflater来压缩数据,InflaterInputStream也是类似。

使用GZipOutputStream和GZipInputStream解压缩

import java.io.BufferedInputStream;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.util.zip.GZIPInputStream;

import java.util.zip.GZIPOutputStream;

public class Client {

public static void main(String[] args) {

byte[] bytes = readFromFile("D:/testdeflate.txt");

System.out.println("before compress: " + bytes.length);

byte[] compressedBytes = readFromFileAndCompress("D:/testdeflate.txt");

System.out.println("after compress: " + compressedBytes.length);

byte[] decompressBytes = readAndDecompress(compressedBytes);

System.out.println("after decompress: " + decompressBytes.length);

}

/**

* 读取文件内容

*

* @param filePath 文件路径

* @return 文件内容

*/

private static byte[] readFromFile(String filePath) {

int len = -1;

byte[] buf = new byte[1024];

try (InputStream input = new BufferedInputStream(new FileInputStream(filePath));

ByteArrayOutputStream output = new ByteArrayOutputStream()) {

while ((len = input.read(buf)) != -1) {

output.write(buf, 0, len);

}

return output.toByteArray();

} catch (Exception e) {

e.printStackTrace();

}

return new byte[0];

}

/**

* 读取文件内容并压缩

*

* @param filePath 文件路径

* @return 文件内容

*/

private static byte[] readFromFileAndCompress(String filePath) {

int len = -1;

byte[] buf = new byte[1024];

try (InputStream input = new BufferedInputStream(new FileInputStream(filePath));

ByteArrayOutputStream output = new ByteArrayOutputStream();

GZIPOutputStream dos = new GZIPOutputStream(output)) {

while ((len = input.read(buf)) != -1) {

dos.write(buf, 0, len);

}

//必须

dos.finish();

return output.toByteArray();

} catch (Exception e) {

e.printStackTrace();

}

return new byte[0];

}

/**

* 读取并解压

*

* @param bytes 待解压数据

* @return 解压之后的数据

*/

private static byte[] readAndDecompress(byte[] bytes) {

int len = -1;

byte[] buf = new byte[1024];

try (InputStream input = new GZIPInputStream(new ByteArrayInputStream(bytes));

ByteArrayOutputStream output = new ByteArrayOutputStream()) {

while ((len = input.read(buf)) != -1) {

output.write(buf, 0, len);

}

return output.toByteArray();

} catch (IOException e) {

e.printStackTrace();

}

return new byte[0];

}

}

输出结果为

before compress: 43435

after compress: 1180

after decompress: 43435

可以看到使用GZip相比Deflater,压缩之后的数据多了一些字节,这是因为GZipOutputStream就是DeflaterOutputStream的扩展类,在数据头部加入了10个字节的header数据,尾部加入了8个字节的CRC32的检验数据。

4a989c41a84fe5114e2f56225f9769e0.png

可以看到Tomcat服务器对响应数据的压缩就使用到了GZipOutputStream。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值