对于目前的状况来说,移动终端的网络状况没有PC网络状况那么理想。在一个Android应用中,如果需要接收来自服务器的大容量数据,那么就不得不考虑客户的流量问题。本文根据笔者的一个项目实战经验出发,解决大容量数据的交互问题,解决数据大小会根据实际情况动态切换问题(服务器动态选择是否要压缩数据,客户端动态解析数据是否是被压缩的),还有数据交互的编码问题。
1 package com.chenjun.utils.compress; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.ByteArrayOutputStream; 5 import java.io.InputStream; 6 import java.io.OutputStream; 7 import java.util.zip.GZIPInputStream; 8 import java.util.zip.GZIPOutputStream; 9 10 public class Compress { 11 private static final int BUFFER_LENGTH = 400; 12 13 14 //压缩字节最小长度,小于这个长度的字节数组不适合压缩,压缩完会更大 15 public static final int BYTE_MIN_LENGTH = 50; 16 17 18 //字节数组是否压缩标志位 19 public static final byte FLAG_GBK_STRING_UNCOMPRESSED_BYTEARRAY = 0; 20 public static final byte FLAG_GBK_STRING_COMPRESSED_BYTEARRAY = 1; 21 public static final byte FLAG_UTF8_STRING_COMPRESSED_BYTEARRAY = 2; 22 public static final byte FLAG_NO_UPDATE_INFO = 3; 23 24 31 public static void compress(InputStream is, OutputStream os) 32 throws Exception { 33 34 GZIPOutputStream gos = new GZIPOutputStream(os); 35 36 int count; 37 byte data[] = new byte[BUFFER_LENGTH]; 38 while ((count = is.read(data, 0, BUFFER_LENGTH)) != -1) { 39 gos.write(data, 0, count); 40 } 41 42 gos.finish(); 43 44 gos.flush(); 45 gos.close(); 46 } 47 48 49 56 public static void decompress(InputStream is, OutputStream os) 57 throws Exception { 58 59 GZIPInputStream gis = new GZIPInputStream(is); 60 61 int count; 62 byte data[] = new byte[BUFFER_LENGTH]; 63 while ((count = gis.read(data, 0, BUFFER_LENGTH)) != -1) { 64 os.write(data, 0, count); 65 } 66 67 gis.close(); 68 } 69 70 77 public static byte[] byteCompress(byte[] data) throws Exception { 78 ByteArrayInputStream bais = new ByteArrayInputStream(data); 79 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 80 81 // 压缩 82 compress(bais, baos); 83 84 byte[] output = baos.toByteArray(); 85 86 baos.flush(); 87 baos.close(); 88 89 bais.close(); 90 91 return output; 92 } 93 94 95 102 public static byte[] byteDecompress(byte[] data) throws Exception { 103 ByteArrayInputStream bais = new ByteArrayInputStream(data); 104 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 105 106 // 解压缩 107 108 decompress(bais, baos); 109 110 data = baos.toByteArray(); 111 112 baos.flush(); 113 baos.close(); 114 115 bais.close(); 116 117 return data; 118 } 119 }
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { JjjzForm jjjzForm = (JjjzForm) form; //基金净值历史走势信息 ArrayList jjjzs = null; //得到基金净值历史走势的方法省略了 Gson gson = new Gson(); String jsonStr = gson.toJson(jjjzs, jjjzs.getClass()); byte[] resultOriginalByte = jsonStr.getBytes(); //组织最后返回数据的缓冲字节数组 ByteArrayOutputStream resultBuffer = new ByteArrayOutputStream(); OutputStream os = null; try { os = response.getOutputStream(); //如果要返回的结果字节数组小于50位,不将压缩 if(resultOriginalByte.length < Compress.BYTE_MIN_LENGTH){ byte flagByte = Compress.FLAG_GBK_STRING_UNCOMPRESSED_BYTEARRAY; resultBuffer.write(flagByte); resultBuffer.write(resultOriginalByte); } else{ byte flagByte = Compress.FLAG_GBK_STRING_COMPRESSED_BYTEARRAY; resultBuffer.write(flagByte); resultBuffer.write(Compress.byteCompress(resultOriginalByte)); } resultBuffer.flush(); resultBuffer.close(); //将最后组织后的字节数组发送给客户端 os.write(resultBuffer.toByteArray()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{ try { os.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; }
byte[] receivedByte = EntityUtils.toByteArray(httpResponse.getEntity()); String result = null; //判断接收到的字节数组是否是压缩过的 if (receivedByte[0] == Compress.FLAG_GBK_STRING_UNCOMPRESSED_BYTEARRAY) { result = new String(receivedByte, 1, receivedByte.length - 1, EXCHANGE_ENCODING); } else if (receivedByte[0] == Compress.FLAG_GBK_STRING_COMPRESSED_BYTEARRAY) { byte[] compressedByte = new byte[receivedByte.length - 1]; for (int i = 0; i < compressedByte.length; i++) { compressedByte[i] = receivedByte[i + 1]; } byte[] resultByte = Compress.byteDecompress(compressedByte); result = new String(resultByte, EXCHANGE_ENCODING); }