Java实现GZIP压缩
2015-08-31 22:21
645 查看
Java实现GZIP压缩
前段时间需要使用到天气预报数据,从网站下载下来之后,发现全部是乱码,一直不明白怎么回事,后来偶然的机会,在查看响应信息时,发现网站在传输响应数据时,使用了gzip压缩,也就是我一直获取到的是压缩后的数据,未经过解压缩就直接使用,所以一直乱码了。下面简单整理一下:GZIP最早由Jean-loup Gailly和Mark Adler创建,用于UNⅨ系统的文件压缩。我们在Linux中经常会用到后缀为.gz的文件,它们就是GZIP格式的。现今已经成为Internet上使用非常普遍的一种数据压缩格式,或者说一种文件格式。
HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来让用户感受更快的速度。这一般是指WWW服务器中安装的一个功能,当有人来访问这个服务器中的网站时,服务器中的这个功能就将网页内容压缩后传输到来访的电脑浏览器中显示出来。一般对纯文本内容可压缩到原大小的40%,这样传输就快了,效果就是你点击网址后会很快的显示出来,当然这也会增加服务器的负载,一般服务器中都安装有这个功能模块的。
下面来写一个简单的示例,看看Java中如何实现GZIP压缩与解压缩。
编写一个服务器端的Servlet,用于向客户端响应传输一个文件,使用GZIP压缩传输的数据内容:
package com.gzip.demo; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.GZIPOutputStream; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * GZIP * * @author 小明 * */ @WebServlet("/download") public class DownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 从响应中获取输入流对象,客户端从输入流中读取数据,另存到文件中 InputStream in = new FileInputStream(request.getServletContext().getRealPath("/") + "Kameo-Hero's Theme.wma"); GZIPOutputStream gzipOut = new GZIPOutputStream(response.getOutputStream()); byte[] b = new byte[1024]; int len; int total = 0; // 文件总大小 while ((len = in.read(b)) != -1) { gzipOut.write(b, 0, len); total += len; } gzipOut.flush(); gzipOut.close(); in.close(); System.out.println("文件大小:" + total); } }
客户端访问Servlet资源,将获取到的响应数据保存到文件中:
package com.gzip.demo; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; /** * 下载测试:未使用gzip解压缩 * * @author 小明 * */ public class Download { public static void main(String[] args) throws IOException { URL url = new URL("http://localhost:8080/GzipDemo/download"); HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); httpURLConnection.setRequestMethod("GET"); httpURLConnection.setConnectTimeout(1000); httpURLConnection.setDoInput(true); httpURLConnection.connect(); if (httpURLConnection.getResponseCode() == 200){ InputStream in = httpURLConnection.getInputStream(); OutputStream out = new FileOutputStream("test.wma"); byte[] b = new byte[1024]; int len; int total = 0; // 接收到的文件大小 while((len = in.read(b)) != -1){ out.write(b, 0, len); total += len; } out.flush(); out.close(); in.close(); System.out.println("响应获取到数据大小:" + total); System.out.println("下载完成"); } } }
对获取到的响应数据未解压缩,查看文件大小:
服务器端:
文件大小:2277129
客户端:
响应获取到数据大小:2231918 下载完成
客户端获取的是压缩后的大小。
使用GZIP解压缩:
package com.gzip.demo; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.zip.GZIPInputStream; /** * 下载测试:未使用gzip解压缩 * * @author 小明 * */ public class Download_GZIP { public static void main(String[] args) throws IOException { URL url = new URL("http://localhost:8080/GzipDemo/download"); HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); httpURLConnection.setRequestMethod("GET"); httpURLConnection.setConnectTimeout(1000); httpURLConnection.setDoInput(true); httpURLConnection.connect(); if (httpURLConnection.getResponseCode() == 200){ InputStream in = new GZIPInputStream(httpURLConnection.getInputStream()); OutputStream out = new FileOutputStream("test2.wma"); byte[] b = new byte[1024]; int len; int total = 0; // 总大小 while((len = in.read(b)) != -1){ out.write(b, 0, len); total += len; } out.flush(); out.close(); in.close(); System.out.println("接收到响应数据大小:" + total); System.out.println("下载成功"); } } }
客户端打印结果:
接收到响应数据大小:2277129 下载成功
示例是压缩的wma文件,如果压缩的是文本文件,则压缩率会更高。
相关文章推荐
- java访问者模式
- RandomAccessFile的用法
- 切换java-javac jdk1.7-jdk1.6
- JAVA中重写和重载的区别
- 001Spring4.2基本环境搭建
- java中的foreach循环
- 本人是一名专科学生,现自学java,记录学习。希望能够大家多多提提意见
- java反射机制之基础
- DesignPattern_Java:Composite Pattern
- spring 的 resource接口概览
- java中Map,List与Set的区别(二)
- spring3.0新特性
- 用java实现冒泡排序法
- 【Java】JAVA枚举类型
- Java连接SQLite数据库
- Java 多线程 并发编程
- Java智力题
- java的匿名内部类
- 【Java】JAVA反射机制
- 【JavaSE】day10_对象流